{"_id":"@buckeyestudio/toh-time-context","name":"@buckeyestudio/toh-time-context","dist-tags":{"next":"0.1.1-rc.2","latest":"0.1.1-rc.2"},"versions":{"0.1.1-rc.2":{"name":"@buckeyestudio/toh-time-context","description":"Opt-in durable per-step context with the current time and elapsed time","version":"0.1.1-rc.2","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/context/time-context"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","author":{"name":"buckeyestudio"},"dependencies":{"@buckeyestudio/schemastery":"^3.18.1"},"peerDependencies":{"@buckeyestudio/toh-agent":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-session":"^0.1.1-rc.2"},"devDependencies":{"@buckeyestudio/toh-agent":"^0.1.1-rc.2","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-agent-loop-testkit":"^0.1.1-rc.2","@buckeyestudio/toh-agent-loop":"^0.1.1-rc.2","@buckeyestudio/toh-llm":"^0.1.1-rc.2","@buckeyestudio/toh-loader-smoke":"^0.1.1-rc.2","@buckeyestudio/toh-session":"^0.1.1-rc.2","@buckeyestudio/toh-system-prompt":"^0.1.1-rc.2","@buckeyestudio/toh-tools":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"_id":"@buckeyestudio/toh-time-context@0.1.1-rc.2","bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","_integrity":"sha512-XETqV1dgy4AHVS7Qq1GNxoqTUCaMpps7Wf145nxKGJ+6bre7X2VOKa1/EUjnFrCwB5SwRk8Q9EYdw7XZcseUFg==","_resolved":"/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-time-context-0.1.1-rc.2.tgz","_from":"file:/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-time-context-0.1.1-rc.2.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-XETqV1dgy4AHVS7Qq1GNxoqTUCaMpps7Wf145nxKGJ+6bre7X2VOKa1/EUjnFrCwB5SwRk8Q9EYdw7XZcseUFg==","shasum":"a875246040d34fce59b361e4ed32fcc1b2ae9edc","tarball":"https://registry.npmjs.org/@buckeyestudio/toh-time-context/-/toh-time-context-0.1.1-rc.2.tgz","fileCount":11,"unpackedSize":51506,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICSvVGWLK87MTbsEanA3k3fZybw5aFPBEcs+9bUhjsbOAiBOyc7W1yPhbT26vGYE/ndGcw0Xpbr7xCyBtaRfzwdtaQ=="}]},"_npmUser":{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"},"directories":{},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toh-time-context_0.1.1-rc.2_1787489552875_0.5964630223366241"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T12:52:32.753Z","0.1.1-rc.2":"2026-08-23T12:52:33.008Z","modified":"2026-08-23T12:52:33.177Z"},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"description":"Opt-in durable per-step context with the current time and elapsed time","homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/context/time-context"},"author":{"name":"buckeyestudio"},"bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"license":"MIT","readme":"# @buckeyestudio/toh-time-context\n\n[English](README.md) | 中文\n\n可选的持久上下文，包含当前带时区时间、附加到当前开放请求的浏览器时区，以及在模型请求准备期间采样的经过时长。默认组合不启用它；Schedule Web overlay 会挂载它，使模型可以按用户的浏览器时区解释未明确限定时区的日期和时间。决策记录：[持久 time-context Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-durable-per-step-time-context.zh.md)。\n\n## 配置\n\n```yaml\n- id: time-context\n  name: '@buckeyestudio/toh-time-context'\n  config:\n    timeZone: Asia/Shanghai  # optional fallback when the request has no unique browser zone\n    refreshIntervalMs: 60000 # optional; omit or set to 0 for every eligible attempt\n```\n\n当当前开放轮次只包含一个经 Host 校验的浏览器时区时，使用该请求本地时区格式化时间戳。浏览器来源信息缺失或混杂时，`timeZone` 提供显示回退；省略它则会在插件加载时解析一次 Node 进程时区。Node 遵循 `TZ`，每个显式回退值都经 `Intl.DateTimeFormat` 校验。\n\n`refreshIntervalMs` 必须是非负安全整数。省略或设为 `0` 时，会为每个信号尚未中止且将进入步骤的合格 pre-step 添加上下文。正数值只会在会话没有更早的 time-context 注入、挂钟时间倒退，或自最新注入起已经过至少相应毫秒数时添加上下文。\n\n## 请求时区归属\n\n浏览器会为每条提示词采样 `Intl.DateTimeFormat().resolvedOptions().timeZone`。Host 校验并规范化该值，再将其绑定到确切的持久 `user-rpc` 消息来源。Time-context 只检查当前开放轮次中的这些来源：唯一一个时区可解析请求，多个时区记为 `mixed`，没有时区则记为 `unavailable`。它不会读取或修改会话标头、连接状态或 Schedule 记录。\n\n解析后的指令告诉模型，把未明确限定时区的日期和时间解释为该浏览器时区。来源信息为 mixed 或 unavailable 时，模型会收到要求用户澄清的指令。这是自然语言上下文，并非另一个包边界上的输入默认值：接受本地日历字段的工具仍自行负责其显式时区要求。\n\n## 时序语义\n\n该插件会前置一个 `agent/pre-step` 监听器，并先行委托下游。需要注入且下游决策进入步骤时，它会向返回批次追加一条带来源的 `UserMessage`。AgentLoop 在 `step/start` 之后、请求派生之前记录最终批次。决策被拒绝、监听器失败或信号已经中止时，不会记录任何内容。\n\n每个读数都使用确切的快照来源 `{ kind: 'plugin', plugin: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text: <same text> }] }`。`./invariant` 配套模块会校验该形状，根据原始 `user-rpc` 消息重新派生当前轮次的浏览器策略，并检查时间戳时区与经过时长基线。\n\n正数间隔调度会扫描原始持久会话事件，查找最新一条归因于插件的消息，其中包括已被压缩（compaction）遮蔽的读数。因此，它无需进程本地缓存也能在恢复后继续生效。正数间隔可以有意让后续请求复用现有历史，而不添加新读数；Schedule Web overlay 会省略该间隔。\n\n第 1 步从最新一条在其之前持久化的用户、助手或工具结果消息起测量。为该步骤拟议的提示词尚未追加。后续步骤从同一轮次中前一个 time-context 事件起测量。缺少基线时报告 `unavailable`，挂钟时间倒退时将经过时长限制为零。\n\n读数记录的是已进入的步骤，不是已完成或已传输的请求。后续准备失败时，该读数可能留在历史中。消息会保留在派生会话历史中，直到压缩将其遮蔽；`request/header` 不含 time-context 状态，请求重建会使用每个 `step/start` 之后的完整持久表层前缀。\n\n## 模型体验\n\n### 准备期时间上下文\n\n#### 模型看到的内容\n\n每条注入消息包含三行。`<timestamp>` 是带数字偏移和 IANA 时区、形如 ISO 的时间戳；持续时间使用紧凑的整秒单位。\n\n##### 第一步\n\n```markdown\nTime sampled while preparing turn <turn>, step 1: <timestamp>\nBrowser time zone for this request: <iana-zone-or-mixed-or-unavailable-policy>.\nElapsed since the preceding model-visible message: <duration-or-unavailable>.\n```\n\n##### 后续步骤\n\n```markdown\nTime sampled while preparing turn <turn>, step <step>: <timestamp>\nBrowser time zone for this request: <iana-zone-or-mixed-or-unavailable-policy>.\nElapsed since the preceding step context: <duration-or-unavailable>.\n```\n\n#### Token 影响\n\n每个读数都会累积，直到压缩将其遮蔽。正数间隔会减少新增读数；省略或设为 `0` 时，每次合格的准备尝试都会添加一条。\n\n#### KV Cache 影响\n\n仅追加；新可见内容位于可复用请求前缀之后，不会使现有 KV Cache 条目失效。\n\n## 已知限制与暂缓事项\n\n- **仅限提示词来源信息**：浏览器时区上下文用于指导自然语言解释，但不会悄然填入另一工具所要求的时区字段。\n- **混合轮次会询问**：如果同一个开放轮次包含来自不同浏览器时区的提示词，模型会收到要求澄清的指令，而不会猜测哪个时区拥有未限定的时间。\n- **回退值不代表用户权威**：浏览器来源信息缺失或混杂时，配置或进程时区用于格式化时钟，但面向模型的策略仍要求澄清。\n- **整秒显示**：时间戳与持续时间省略亚秒精度，尽管持久事件时间保留毫秒。\n- **压缩之间的历史成本**：省略或设为 `0` 时，每次合格尝试都会保留一条读数；正数间隔可以降低但无法消除该成本，也可能使后续请求缺少新鲜的浏览器时区指导。\n","readmeFilename":"README.zh.md","_rev":"1-b1e24df526a11fe439cd6946d3516cd1"}