* fix(session-projection): keep released units in checkpoints Since the Cordis rc.11 teardown order unloads the Web layer before the base layer, Session Controller and harness-dev-context release their projection units before their live Sessions detach. The projection cache is still alive at that point and wrote a checkpoint holding only the units that were still registered, replacing the complete record. A blank Session then lost sessionListMetadata and listed as an untitled conversation after every graceful restart. A released unit now stays in the registry as a predecessor: it leaves event drives, snapshots, restores, and change notifications, while checkpoint() keeps each Session's last cell of it without advancing it. Registering the same key again replaces the predecessor and refolds the log. The projection cache keeps replacing whole records. * test(session-projection): assert frozen released units across unload tests Update the remaining unload tests that still expected a released unit to vanish from checkpoint(): user-approval, agent-loop inbox and scope lifecycle, time-context, and the agent registry now assert that the same Session keeps its pre-unload row, that a later event does not advance it, and that a Session created after the unload has no row. The token-meter and goal unload tests also append an event after the unload. Document that a retained handle read still advances a released cell that checkpoint() serves, and that restore() folds only live units, so its refreshed rows omit released units. * docs(session-projection): sync the ProjectionHandle type-equiv block * docs(session-projection): record frozen released units and their upgrade Add the upgrade guide for checkpoint() keeping a released unit's last row, update the registration-handles Agent Note with the frozen-cell decision and the retained predecessor, list both consequences under the registry README's known limitations, note in the projection cache README that a stored row can be frozen at its unit's release, and say that restoreFloor() ignores released predecessors. Update the agent-loop resource-lifecycle unload test, which read checkpoints through an alias, to the frozen-row semantics. * docs(upgrade-guide): mark the released-checkpoint snippet ignore-check * docs(session-projection): state the retained-handle path and narrow a rejected alternative * docs(upgrade-guide): re-record the released-checkpoint guide pairing
description, kind
| description | kind |
|---|---|
| Per-step clock context with the current time, browser zone, and elapsed time, for users and maintainers tuning the plugin. | package-reference |
@deepseek-ai/dsh-time-context
English | 中文
Summary
dsh-time-context gives the model a clock: on eligible steps it appends a durable, source-attributed reading with the current time, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. It helps the model interpret otherwise-unqualified dates and times in the user's browser zone, and tells it to ask when current-turn browser zones are mixed or missing. The shipped Web composition carries no row for it; standard, cordis, and ptc declare it. Readings default to a 10-minute minimum interval; refreshIntervalMs: 0 injects at every eligible step.
Table of Contents
- Use this package
- Understand the implementation
- Further Exploration
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Mount this plugin when the model should interpret unqualified dates and times in the user's zone, and when a request-local browser zone is available or a configured fallback is acceptable. Each injection is one additional user-role message in the durable history; schedule it with refreshIntervalMs when per-step readings are more than the conversation needs. The shipped Web composition carries no Host time-context row, and the standard, cordis, and ptc presets declare it beside the reminder tools that consume it, while minimal declares neither.
What the model gets
Each injected reading has three lines: an ISO-shaped timestamp with numeric offset and IANA zone, the browser-zone policy for the request, and the elapsed duration in compact whole-second units. Step 1 measures from the latest preceding model-visible message; later steps measure from the preceding time-context event in the same turn. A missing baseline reports unavailable, and backward wall-clock movement clamps elapsed time to zero.
Configuration
The minimal mount needs no configuration. A positive refreshIntervalMs suppresses injections that fall within that many milliseconds of the latest one; omission uses 600000 ms (10 minutes), while 0 injects at every eligible entering pre-step whose signal is not already aborted.
- name: '@deepseek-ai/dsh-time-context'
config:
timeZone: Asia/Shanghai
| Field | Default | Meaning |
|---|---|---|
timeZone |
process zone | Fallback display zone when the open turn has no unique browser zone |
refreshIntervalMs |
600000 (10 minutes) |
Minimum milliseconds between durable injections in one session |
The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc.
Choosing the zone
When the open turn contains exactly one Host-validated browser zone, the timestamp is formatted in that request-local zone. With missing or mixed browser-zone records, the configured timeZone formats the display; omitting it resolves the Node process zone once at plugin load, and every explicit fallback is validated through Intl.DateTimeFormat. The resolved instruction tells the model to interpret unqualified dates and times in the chosen zone, and to ask the user to clarify when those records are mixed or unavailable.
Understand the implementation
Implementation internals — click to expand
This section explains the design of the plugin; the observable behavior is covered in Use this package.
Design concept
The plugin prepends an agent/pre-step listener that delegates first and appends one sourced UserMessage when an injection is due and the downstream decision enters the step. Each reading uses the exact snapshot source { kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text }] }.
Source map
| File | Role |
|---|---|
src/index.ts |
Plugin entry: pre-step listener, due scheduling, reading composition |
src/request-zone.ts |
Browser-zone policy derivation from open-turn user-rpc sources |
src/timestamp.ts |
Intl.DateTimeFormat creation and timestamp formatting |
Main flow
The pre-step listener is installed before awaiting projection registration. Steps arriving during activation wait for the reader; registration failure or owner disposal stops the request, and cancellation while waiting produces no reading.
When an injection is due, the plugin samples the wall clock, derives the browser-zone policy, resolves the display zone (request-local or fallback), and renders the three-line reading. The private timeContext Projection stores message and injection times, the latest entered turn, and its distinct reported browser zones in encounter order. It retains zone facts from messages shadowed by compaction. Zone validation stays after rejection and refresh checks; replay does not invoke formatters or hooks. JSON checkpoints plus suffix replay match a full replay. Older-version cache rows rebuild from the full journal. A reading records an entered step, not a completed or transmitted request; a later preparation failure can leave it in history.
Further Exploration
Read these pages when the package-level contract is not enough. They move from the design decision to the composition that mounts the plugin and the exhaustive configuration.
- Schedule user guide — the official configuration path for mounting this plugin.
- Context group map — sibling request-context packages.
- Generated configuration catalog — every accepted config field and its source declaration.
Model Experience
Preparation-time temporal context
What the model sees
Each injected message contains three lines. <timestamp> is an ISO-shaped timestamp with numeric offset and IANA zone; durations use compact whole-second units.
First step
Time sampled while preparing turn <turn>, step 1: <timestamp>
Browser time zone for this request: <iana-zone-or-mixed-or-unavailable-policy>.
Elapsed since the preceding model-visible message: <duration-or-unavailable>.
Later steps
Time sampled while preparing turn <turn>, step <step>: <timestamp>
Browser time zone for this request: <iana-zone-or-mixed-or-unavailable-policy>.
Elapsed since the preceding step context: <duration-or-unavailable>.
Token effect
Each reading accumulates until compaction shadows it. A positive interval reduces additions; 0 adds one at every eligible preparation attempt.
KV Cache effect
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV Cache entries.
Known Limitations and Deferred Work
These limits define when clock context is a poor fit. They are current package constraints.
- State and replay cost — timestamps and the current turn number have fixed size. Zone state grows with distinct reported strings in the latest entered turn, not all messages; each new distinct zone copies that list. Formatters remain discardable process caches. The standard AgentLoop requests its latest entered turn. If a typed pre-step caller requests another turn, the original full-prefix synchronous scan includes later entered messages. Retiring this fallback requires limiting pre-step requests to the latest entered turn and updating callers together.
- Prompt guidance only — browser-zone context guides natural-language interpretation but does not silently supply another tool's required zone field.
- Mixed turns ask — if one open turn contains prompts from different browser zones, the model is told to clarify rather than guess which one owns an unqualified time.
- Fallback is not user authority — the configured or process zone formats the clock when current-turn browser zones are missing or mixed, but the model-facing policy still says to clarify.
- Whole-second display — timestamps and durations omit sub-second precision even though durable event times retain milliseconds.
- History cost between compactions —
0retains one reading for every eligible attempt; a positive interval reduces but does not eliminate this cost and may leave a later request without fresh browser-zone guidance.
Dev Note
Working context for maintainers — click to expand
None.