{"_id":"@buckeyestudio/toh-session-reference","name":"@buckeyestudio/toh-session-reference","dist-tags":{"next":"0.1.1-rc.2","latest":"0.1.1-rc.2"},"versions":{"0.1.1-rc.2":{"name":"@buckeyestudio/toh-session-reference","description":"Cross-session snapshot references and durable untrusted model context (ctx.sessionReferenceResolver)","version":"0.1.1-rc.2","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/context/session-reference"},"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"},"./types":{"types":"./lib/types/types.d.ts","default":"./lib/types/types.js"},"./typert":{"types":"./lib/typert.host.d.ts","default":"./lib/typert.host.js"},"./remote":{"types":"./lib/typert.remote-client.d.ts","default":"./lib/typert.remote-client.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","author":{"name":"buckeyestudio"},"dependencies":{"zod":"^4.4.3","@buckeyestudio/schemastery":"^3.18.1"},"peerDependencies":{"@buckeyestudio/toh-agent":"^0.1.1-rc.2","@buckeyestudio/toh-compaction":"^0.1.1-rc.2","@buckeyestudio/toh-llm":"^0.1.1-rc.2","@buckeyestudio/toh-output-retention":"^0.1.1-rc.2","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-session":"^0.1.1-rc.2","@buckeyestudio/toh-session-query":"^0.1.1-rc.2","@buckeyestudio/toh-typert-protocol":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"devDependencies":{"@buckeyestudio/toh-compaction":"^0.1.1-rc.2","@buckeyestudio/toh-agent":"^0.1.1-rc.2","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-llm":"^0.1.1-rc.2","@buckeyestudio/toh-output-retention":"^0.1.1-rc.2","@buckeyestudio/toh-session":"^0.1.1-rc.2","@buckeyestudio/toh-session-query":"^0.1.1-rc.2","@buckeyestudio/toh-typert-protocol":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"_id":"@buckeyestudio/toh-session-reference@0.1.1-rc.2","bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","_integrity":"sha512-3ETU34yXUUJz1yNLThP+2GVxRrhku2DNppL8L97a8qeWnGxX/HZBE2OgLfsaZDE1o5X4Npy4mlDKs4Bp+wjFjQ==","_resolved":"/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-session-reference-0.1.1-rc.2.tgz","_from":"file:/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-session-reference-0.1.1-rc.2.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-3ETU34yXUUJz1yNLThP+2GVxRrhku2DNppL8L97a8qeWnGxX/HZBE2OgLfsaZDE1o5X4Npy4mlDKs4Bp+wjFjQ==","shasum":"802acc09e168417bc66cdb6b42be29d801c6d85a","tarball":"https://registry.npmjs.org/@buckeyestudio/toh-session-reference/-/toh-session-reference-0.1.1-rc.2.tgz","fileCount":25,"unpackedSize":118237,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD7RfLRlj275nP1tLdeQxzSVZQrFsMr3DCDnlFzXA4hbAIhAP+wr6iHpiTioEIoovzJ+ERzyd9sPjdysofIr1oAvg9j"}]},"_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-session-reference_0.1.1-rc.2_1787489085301_0.41483574596844686"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T12:44:45.205Z","0.1.1-rc.2":"2026-08-23T12:44:45.449Z","modified":"2026-08-23T12:44:45.609Z"},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"description":"Cross-session snapshot references and durable untrusted model context (ctx.sessionReferenceResolver)","homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/context/session-reference"},"author":{"name":"buckeyestudio"},"bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"license":"MIT","readme":"# `@buckeyestudio/toh-session-reference`\n\n[English](README.md) | 中文\n\n`ctx.sessionReferenceResolver` 会把其他会话准备为有界、只读快照，作为带来源信息、面向模型的上下文。它消费 `ctx.sessionQuery` 与后端无关的 compact 检查点标记；不需要 SQLite FTS。支持跨会话 mention 的宿主可以主动启用该服务。\n\n## 公开 API\n\n- `listCandidates(agent, query?, limit?)` 会列出 `agent.id` 之外的会话，按 id、cwd 或以日志为依据的最新标题进行不区分大小写的筛选，再按同 cwd、无 cwd、其他 cwd 记录排序，同时保持每组内的 `listSessions()` 创建顺序。每个已选候选会话都使用该标题作为 mention label；标题不存在或无法读取时回退到会话 id。不搜索消息主体。一元 `sessionReferenceResolver/candidates` Remote 方法在配置的候选上限内提供同一发现能力，并为每个候选附上规范 mention，浏览器消费方直接调用 `ctx.remote.sessionReferenceResolver.candidates`，无需 API Proxy 路由。\n- `prepare(agent, content, references, signal?)` 会保留首次 mention 顺序、对 id 去重，并拒绝自引用或超过已配置不同源上限的情况。它会并行读取所有源，返回与输入脱离的内容，外加零个或一个聚合且带标识的 `UserMessage` 上下文。下游 `agent/pre-step` 监听器接受步骤后，该服务会针对直接用户消息中的规范 mention 调用此方法。\n- `encodeSessionReferenceUri()` 与 `decodeSessionReferenceUri()` 实现 `toh-session:<base64url(JSON.stringify(sessionId))>`，因此每个 JavaScript 字符串 id 都能精确往返。`formatSessionReferenceMention()` 发出 `@[label](uri)`，`parseSessionReferenceText()` 将 Markdown mention 或裸规范 URI 替换为可读的 `@label` 文本，并返回结构化引用。解析器会拒绝显式 Markdown mention 中任何格式错误的 URI；只当 scheme 后跟非空、符合 base64url 形状的 payload 时，裸文本才被视为引用，匹配但非规范的候选项仍会失败。空 scheme mention 或只含标点符号的 scheme mention 仍是普通讨论文本。\n\n## 快照语义\n\n目标消息到达 `agent/pre-step` 时，准备阶段会对每个不同源调用一次 `ctx.sessionQuery.readSurface()`。因此，queued 消息在进入模型步骤时捕获源状态，此后生成的上下文保持不变。它仅投影折叠后当前表层中的用户直接发出的 `user/message`、assistant 文本，以及 `user/message` 检查点；这类检查点携带规范 `toh-compaction` 源标记。带独立来源的 session-reference 消息属于注入上下文，会被排除以防止快照递归传播。已遮蔽的压缩（compaction）前事件、工具、推理（reasoning）、除已标记 compact 检查点外的其他插件生成 user 消息，以及未完成的 assistant 分片也都会被排除。因此，已压缩源只会提供最新检查点及其后保留的会话内容，不会还原已遮蔽的文本。\n\n上下文源为 `{ kind: 'session-reference', version: 1, references }`；每条引用会记录其源 id 与 label、捕获 seq、是否存在 compact、已保留／已省略消息数、已省略 UTF-8 字节数与截断状态。该服务的外层 `agent/pre-step` 监听器会处理已接受的直接用户消息，保留其消息 id，并把每份快照插入到引用它的消息紧后。解析发生在最终领取收件箱消息之后，因此队列编辑和从 queue 移动到 steer 不需要引用专用处理。无效 mention、读取失败、取消和预算失败会在消息进入面向模型的历史之前结束该轮次。目标日志会先记录可读的直接 `user/message`，再记录其带来源信息的上下文 `user/message`；捕获后的源变更无法改变目标回放。\n\n## 配置\n\n| Key | 默认值 | 约定 |\n|---|---:|---|\n| `maxReferences` | `3` | 一条已准备消息中不同源会话的最大数量；必须不大于 `3`。 |\n| `candidateLimit` | `50` | 返回给宿主的默认候选数量。 |\n| `maxReferenceBytes` | `65536` | 一个引用对象的最大序列化 JSON 字节数。 |\n\n保留会对每个源独立应用 `maxReferenceBytes`，保留 compact 检查点与最新消息，再丢弃较旧的非检查点单元，并使用 `toh-output-retention` 头部／尾部截断和精确 UTF-8 省略通知。如果某个源的固定序列化字段本身就超出限额，准备会以 `SESSION_REFERENCE_BUDGET_EXCEEDED` 失败，而不返回部分上下文。\n\n## 模型体验\n\n### 引用会话背景\n\n#### 模型看到的内容\n\n模型会看到两条连续的 user 角色消息：先是带可读 `@label` 的当前消息，再是 `## Referenced sessions` 不受信任快照。警告禁止遵循快照中的指令、权限声明或工具请求，除非当前用户明确重复这些内容。标签、cwd 值、id 与会话文本会作为 JSON 在 `<referenced-sessions>` 标签中序列化；数据中的每个 `<` 都会以无损 JSON 转义 `\\u003c` 的形式发出，因此源文本无法拼出定界标签。\n\n#### Token 影响\n\n每条包含引用的消息都会添加固定警告和最多三个序列化快照，每个快照都受 `maxReferenceBytes` 独立限制。精确快照会保留在目标历史中，直到目标压缩遮蔽或摘要它；源会话变更不会添加更多 token。\n\n#### KV Cache 影响\n\n请求与快照是两条连续、仅追加的目标消息，并保留较早的可缓存历史。不同引用或源捕获内容只改变新后缀；后续目标压缩可能使从替换边界起的复用失效。\n\n## 已知限制与暂缓事项\n\n- **不支持消息正文检索**：候选查询会检查折叠后的标题，但不搜索消息主体。非空查询可能通过 session-query 服务有界、可取消的批处理检查每个可见的持久化会话日志；专用标题索引未来可以替换这条发现路径，而不改变 URI、快照或持久化约定。\n- **受信任调用方边界**：该服务假设宿主有权读取 `ctx.sessionQuery` 公开的每个会话；它不是面向模型的搜索工具。\n- **只投影文本**：不会在会话间传播非文本 user 与 assistant 块。\n- **没有实时链接**：引用是快照，不是 fork、恢复、订阅或源会话变更。\n","readmeFilename":"README.zh.md","_rev":"1-7c132423e9a5b89f82e2904f4d0c436f"}