diff --git a/.agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml b/.agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml similarity index 67% rename from .agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml rename to .agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml index 79ba95b677..212dd5d306 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml +++ b/.agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.md -2026-09-11-session-controller-fork-turn-cut.md: 0c8d45c861df964a62586827e80c613704ed17f0 -2026-09-11-session-controller-fork-turn-cut.zh.md: 729a42a596264ac618608d26cd52a1ad836b58db +2026-09-11-session-controller-fork-turn-cut.md: 9223acd4c0c7bbcc84a0bfeb72f3b57d4bf828e2 +2026-09-11-session-controller-fork-turn-cut.zh.md: cae022ae97896c0b43633edb310afb305d690b4a diff --git a/.agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.md b/.agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.md similarity index 99% rename from .agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.md rename to .agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.md index 0c8d45c861..9223acd4c0 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.md +++ b/.agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.md @@ -1,6 +1,7 @@ # Agent Note: Session Controller forks stop at the selected turn end Status: implemented +Archived: 2026-09-16 English | [中文](2026-09-11-session-controller-fork-turn-cut.zh.md) diff --git a/.agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md b/.agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md similarity index 96% rename from .agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md rename to .agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md index 729a42a596..cae022ae97 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md +++ b/.agents/notes/archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md @@ -1,8 +1,9 @@ # Agent Note: Session Controller 分叉截到选中轮次的结束事件 Status: implemented +Archived: 2026-09-16 -English | [中文](2026-09-11-session-controller-fork-turn-cut.md) +[English](2026-09-11-session-controller-fork-turn-cut.md) | 中文 ## Problem diff --git a/.agents/notes/archived/manifest.json b/.agents/notes/archived/manifest.json index 926441caeb..88573f7db2 100644 --- a/.agents/notes/archived/manifest.json +++ b/.agents/notes/archived/manifest.json @@ -751,6 +751,9 @@ "bug-fix/2026-09-09-content-sized-diagram-previews.i18n.yaml": "sha256:a4404fe8e35ca5b6371f9cdb58fea6724cf3e7737bb2db8a3a321d534454b17c", "bug-fix/2026-09-09-content-sized-diagram-previews.md": "sha256:5239e98e5c057d6f7e10c3f10a0f67273778d99b0c4f10b31a1921c3c6474b80", "bug-fix/2026-09-09-content-sized-diagram-previews.zh.md": "sha256:c1ee3790a9d5c3561e1d93d5e649afa904c7d19b9d77248c85ef16daccd953e2", + "bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml": "sha256:4442529ced1c8e48d30f7b50c65ff03eb92dce9815beb438cedbf29f234bce47", + "bug-fix/2026-09-11-session-controller-fork-turn-cut.md": "sha256:a996f24a896c7fc5d81e015db3eae27d8a46c853287572e815623ce35eae1b12", + "bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md": "sha256:6486f0eacf5067ef9850dc32f1c27b2109a7d4e9e3c498366f5c38742bb53ac5", "feature/2026-06-14-acp-agent-client-protocol.i18n.yaml": "sha256:006795baa43ae962a8d125cc0f1e9f134bc2ee9fb758b6e7669e3fa0126e1918", "feature/2026-06-14-acp-agent-client-protocol.md": "sha256:6828c0af74bb3fb96206ca6b21c0e56a000b50e4744aad4bc2c05092f3a5a31b", "feature/2026-06-14-acp-agent-client-protocol.zh.md": "sha256:ba104e841a1fb84edbd3b6c8119d50445b7785255a7a8d13bb9ac8a2cb4d2e69", diff --git a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml index 98850aed4c..b62c09f26c 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md -2026-06-11-content-block-vocabulary.md: d7d3f6b43a3f65d1421f026e5b6c2cc1ba1eadd2 -2026-06-11-content-block-vocabulary.zh.md: ed4f915dff6dcb6dbc91400f9bfa5384253aea7b +2026-06-11-content-block-vocabulary.md: 917dd5225fdc4ab391e9e4629769abbb68095731 +2026-06-11-content-block-vocabulary.zh.md: 9d228eb34dafbdebab44b45dc3b290c9327d3b2b diff --git a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md index d7d3f6b43a..917dd5225f 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md +++ b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md @@ -10,7 +10,7 @@ The harness needs one internal language for messages that the loop, session log, ## Decision -Own the vocabulary: messages are arrays of typed content blocks (`text`, `reasoning`, `tool-call`, `tool-result`), with the union derived from the merge-extensible `ContentBlockMap` so plugins add block types via declaration merging. The same merge-extensible-map pattern types every "stringly" field (`MessageSource`, `FinishReason`, `TurnTrigger`, `TurnEndReason`). Streaming is a raw chunk protocol; `BlockAssembler` is the single shared assembly implementation. Adapters translate to provider wire formats — mapping cost lives in adapters, where it belongs. +Own the vocabulary: user, assistant, and system messages are arrays of typed content blocks (`text`, `reasoning`, `tool-call`), with the union derived from the merge-extensible `ContentBlockMap` so plugins add block types via declaration merging. Tool results are first-class tool-role messages whose own content holds result blocks; released Session format v3 retains the historical `tool-result` content block inside a user-role wrapper, and the adjacent V3-to-V4 edge lifts that wrapper into the first-class role. The same merge-extensible-map pattern types every "stringly" field (`MessageSource`, `FinishReason`, `TurnTrigger`, `TurnEndReason`). Streaming is a raw chunk protocol; `BlockAssembler` is the single shared assembly implementation. Adapters translate to provider wire formats — mapping cost lives in adapters, where it belongs. In-session context injection (`context/message`) and mid-turn steering originally rendered as tagged user-role envelopes (the system-reminder pattern) rather than a new role, so adapters carry zero burden. Both now project as plain user content with no wrapper; see [the injected-content-envelope Agent Note](../simplification/2026-07-20-unwrap-injected-content-envelopes.md). Live-adapter validation confirms this rendering for current DeepSeek behavior; a future provider-specific mismatch belongs in that adapter rather than a new canonical role. diff --git a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md index ed4f915dff..9d228eb34d 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md @@ -10,7 +10,7 @@ harness 需要一套统一的内部消息语言,供 agent loop(智能体循 ## 决策 -自主拥有词汇:消息是类型化内容块的数组(`text`、`reasoning`、`tool-call`、`tool-result`),其联合类型派生自可合并扩展的 `ContentBlockMap`,插件通过声明合并添加新的块类型。同一可合并扩展映射模式为所有「字符串化」字段提供类型(`MessageSource`、`FinishReason`、`TurnTrigger`、`TurnEndReason`)。流式输出采用原始分片协议;`BlockAssembler` 是唯一的共享组装实现。适配器负责转换为提供方的协议格式(wire format)——映射成本留在适配器中,正是它该在的地方。 +自主拥有词汇:user、assistant 与 system 消息是类型化内容块的数组(`text`、`reasoning`、`tool-call`),其联合类型派生自可合并扩展的 `ContentBlockMap`,插件通过声明合并添加新的块类型。Tool result 是一等 tool-role message,结果块属于该 message 自己的 content;已发布的 Session format v3 仍将历史 `tool-result` content block 保存在 user-role 包装中,邻接的 V3 到 V4 边会将该包装提升为一等角色。同一可合并扩展映射模式为所有「字符串化」字段提供类型(`MessageSource`、`FinishReason`、`TurnTrigger`、`TurnEndReason`)。流式输出采用原始分片协议;`BlockAssembler` 是唯一的共享组装实现。适配器负责转换为提供方的协议格式(wire format)——映射成本留在适配器中,正是它该在的地方。 会话内上下文注入(`context/message`)和轮次中途 steering(中途引导)最初渲染为带标签的 user-role 信封(system-reminder 模式),而非引入新角色,因此适配器无需承担额外负担。如今两者都投影为无包装的普通用户内容;见[注入内容信封 Agent Note](../simplification/2026-07-20-unwrap-injected-content-envelopes.zh.md)。实际适配器验证已确认此渲染方式符合当前 DeepSeek 的行为;如果未来某提供方出现不兼容,应在该适配器内处理,而非引入新的规范角色。 diff --git a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml index 1b91468214..56d5cea939 100644 --- a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.md -2026-07-28-identified-immutable-message-values.md: 9d2b22a5a1fc87ea7b0ff8eb24b2e8c4b86543e1 -2026-07-28-identified-immutable-message-values.zh.md: 6b36cfec0a24196ca526b0ffb21180967aa640eb +2026-07-28-identified-immutable-message-values.md: 73c9c14479117cf654d10b3da23d155cca77054d +2026-07-28-identified-immutable-message-values.zh.md: 7a5b9d6524beff01ac8a9e2020f75093271b7ab3 diff --git a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.md b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.md index 9d2b22a5a1..73c9c14479 100644 --- a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.md +++ b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.md @@ -16,7 +16,7 @@ This made identity a routing side effect rather than a message invariant. Produc `createMessage(input)` is the canonical role-generic creation boundary. It mints a `MessageId`, detaches the supplied role, content, and source, and deep-freezes the complete value before returning it. `createUserMessage({ content, source })` fixes the user role for prompt and context producers. `createAssistantMessage({ content, source })` fixes both the assistant role and the model source kind, so model-output producers supply only content plus provider, model, and optional replay state. All creation helpers exclude an input id so callers cannot accidentally present creation as import. `freezeMessage(message)` is the separate import or transformation boundary: it detaches and deep-freezes a message whose identity already exists, without minting a replacement. -The message helpers live in `dsh-llm` beside the base message vocabulary because their complete contracts depend only on that vocabulary. They use `dsh-brand`'s stateless `brandString()` constructor for `MessageId` and `dsh-util-values`'s shared `deepFreeze()` implementation after detaching input with `structuredClone()`. `createToolResultMessage()` belongs with the other creation helpers: it couples a tool call id to the exact user-role tool-result block and source without depending on session state or events. `dsh-session` consumes complete messages rather than owning their construction. +The message helpers live in `dsh-llm` beside the base message vocabulary because their complete contracts depend only on that vocabulary. They use `dsh-brand`'s stateless `brandString()` constructor for `MessageId` and `dsh-util-values`'s shared `deepFreeze()` implementation after detaching input with `structuredClone()`. `createToolResultMessage()` belongs with the other creation helpers: it couples a tool call id to a tool-role message carrying the result content, error state, and source without depending on session state or events. `dsh-session` consumes complete messages rather than owning their construction. The `Agent` interface accepts a complete `UserMessage` through `followup`, `steer`, and `inject`. These operations never allocate or return identity; they freeze an imported value whose id the caller already holds. Inbox claims and `agent/pre-step` receive that message directly. A content rewrite creates a frozen replacement with the same id, while an additional context is a separately created `UserMessage` with its own id. diff --git a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.zh.md b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.zh.md index 6b36cfec0a..7a5b9d6524 100644 --- a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.zh.md +++ b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.zh.md @@ -16,7 +16,7 @@ harness 曾存在多种形似消息的表示,各自采用不同的标识规则 `createMessage(input)` 是角色通用的规范创建边界。它会生成 `MessageId`,将传入的角色、内容和来源与调用方对象解除引用关系,并在返回完整值前将其深度冻结。`createUserMessage({ content, source })` 为提示词和上下文生产方固定 user 角色。`createAssistantMessage({ content, source })` 同时固定 assistant 角色与模型来源类别,因此模型输出生产方只需提供内容,以及提供方、模型和可选的回放状态。所有创建辅助函数的输入都不包含 id,因此调用方不会意外地把新消息的创建伪装成已有消息的导入。`freezeMessage(message)` 是独立的导入或转换边界:它会将已有标识的消息与调用方对象解除引用关系并深度冻结,不会生成替代标识。 -消息辅助函数位于基础消息词汇旁的 `dsh-llm` 中,因为它们的完整约定只依赖该词汇。它们使用 `dsh-brand` 的无状态 `brandString()` 构造函数生成 `MessageId`,并在通过 `structuredClone()` 分离输入后使用 `dsh-util-values` 的共享 `deepFreeze()` 实现。`createToolResultMessage()` 与其他创建辅助函数同属此处:它将工具调用 id 与确切的 user-role 工具结果块及来源耦合起来,不依赖会话状态或事件。`dsh-session` 只消费完整消息,不负责构造它们。 +消息辅助函数位于基础消息词汇旁的 `dsh-llm` 中,因为它们的完整约定只依赖该词汇。它们使用 `dsh-brand` 的无状态 `brandString()` 构造函数生成 `MessageId`,并在通过 `structuredClone()` 分离输入后使用 `dsh-util-values` 的共享 `deepFreeze()` 实现。`createToolResultMessage()` 与其他创建辅助函数同属此处:它将工具调用 id 与携带结果内容、错误状态及来源的 tool-role 消息耦合起来,不依赖会话状态或事件。`dsh-session` 只消费完整消息,不负责构造它们。 `Agent` 接口通过 `followup`、`steer` 和 `inject` 接收完整的 `UserMessage`。这些操作绝不会分配或返回标识;它们会冻结导入的值,而调用方已经持有该值的 id。inbox 领取和 `agent/pre-step` 会直接接收该消息。改写内容时会创建具有相同 id 的冻结替代值,而每个附加上下文都是单独创建的 `UserMessage`,拥有自己的 id。 diff --git a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml index 94db853913..9a020189ec 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md -2026-08-10-session-log-version-mechanism.md: 513b126d3b00841f71893715cc296cb67619543e -2026-08-10-session-log-version-mechanism.zh.md: 919bfb077c7037da2ebf7eb81b75745d6b4fe4d0 +2026-08-10-session-log-version-mechanism.md: 9cb0940f767aa27d5a5106fb78b528c1e3e2695b +2026-08-10-session-log-version-mechanism.zh.md: e1424f24e5dd74b243fe1f0aebceb5d420b9b8c3 diff --git a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md index 513b126d3b..9cb0940f76 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md +++ b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md @@ -18,6 +18,8 @@ Session logs must be upgradable after release, and the runtime that ships first **A per-event `ignorable` marker covers vocabulary growth, so ordinary event additions never bump the version.** The event vocabulary is decided by which plugins are mounted, which a single version integer cannot describe. A reader meeting an unrecognized event type refuses to interpret the log unless the event carries `ignorable: true` in its envelope. The default is *required*: forgetting the marker over-refuses a resumable session (an inconvenience), while a default of ignorable would make the same mistake silently resume a gutted one (a safety failure). The architecture makes this sound: model-visible content flows only through the four `surfaceOp`-marked surface event types plus the `request/header`/`request/context` folds, so the dangerous unknowns are exactly the non-surface events that change how the rest of the log is read (`session/end-seed` is the existing example). +The [accepted compatibility checkpoint](../../../../docs/session-format-status.md#finalization-record) prevents an accepted transition from reusing its header increase for later breaking changes. Backward-compatible evolution uses new acknowledgement records at the same Session version; breaking changes require a higher writer. The checkpoint does not change the unknown-event protocol. + ### Writer and publication authority `SESSION_FORMAT_VERSION` owns the checkout writer number; the [release-status reference](../../../../docs/session-format-status.md) owns one bilingual `latestReleasedVersion` and `evidenceTag` record. Publication changes independently of source development, so status is derived by comparing those facts rather than maintaining a second `released` boolean. General documentation links to these authorities; fixed-version contracts and historical evidence keep their explicit numbers. diff --git a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md index 919bfb077c..e1424f24e5 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md +++ b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md @@ -18,6 +18,8 @@ Session log 在发布后必须能升级格式,而最先发布的运行时决 **逐事件的 `ignorable` 标记吸收词汇表增长,普通的新增事件永远不用升版本。**事件词汇表由挂载了哪些插件决定,单个版本整数描述不了它。读取器遇到不认识的事件类型时拒绝解读日志,除非该事件的信封带 `ignorable: true`。默认为必需:忘写标记的后果是把一个本可恢复的会话拒绝过头(体验问题),而默认可忽略会让同样的疏忽静默恢复出残缺会话(安全事故)。架构保证了这条规则成立:模型可见内容只经四种带 `surfaceOp` 标记的 surface 事件加 `request/header`、`request/context` 折叠进入重建,危险的未知事件恰好是那些不进 surface 但改变日志其余部分解读方式的事件(`session/end-seed` 是现存例子)。 +[已接受兼容性检查点](../../../../docs/session-format-status.zh.md#finalization-record)阻止已接受转换复用原来的头版本递增来授权后续破坏性变更。向后兼容的演进在相同 Session 版本上使用新的确认记录;破坏性变更要求更高的写入器版本。检查点不改变未知事件协议。 + ### 写入器与发布真源 `SESSION_FORMAT_VERSION` 拥有工作区写入器版本号;[发布状态参考](../../../../docs/session-format-status.zh.md)拥有唯一的双语 `latestReleasedVersion` 与 `evidenceTag` 记录。发布状态独立于源码开发而变化,因此通过比较这两个事实推导状态,而不另行维护 `released` 布尔值。一般文档链接到这些真源;固定版本约定与历史证据保留明确版本号。 diff --git a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml index 9e913ccb88..6fa3c9e31b 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md -2026-08-25-electron-desktop-packaging-and-updates.md: c4940942a8d5188faf1846158873c052a43e1fc1 -2026-08-25-electron-desktop-packaging-and-updates.zh.md: 011624980f6f7239a33fb2b6c6803646b7d41dd3 +2026-08-25-electron-desktop-packaging-and-updates.md: f58e8dc471faeb717dd79d32df4afc1b5cc3458f +2026-08-25-electron-desktop-packaging-and-updates.zh.md: 2d2d5c68f28974b606693d5b6727c864c92a0763 diff --git a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md index c4940942a8..f58e8dc471 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md +++ b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md @@ -40,6 +40,8 @@ The Desktop Host exposes the shared Web plugin manager for its reserved profile The renderer uses `nodeIntegration: false`, `contextIsolation: true`, and `sandbox: true`. Preload provides boot readiness and failure reporting, native directory selection, theme synchronization, and Windows menu and appearance adapters. It exposes no raw `ipcRenderer`, filesystem access, shell commands, or pnpm arguments. Electron menus and native dialogs use typed English or Chinese copy with English fallback; Windows follows the main document’s language. The shared Web plugin manager owns its client copy. +Update confirmations use the shell static origin because they must remain available without a ready Web Host. Their packaged documents and assets retain the same method and path restrictions as other local static assets. + ## Filesystem layout ```text diff --git a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.zh.md b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.zh.md index 011624980f..2d2d5c68f2 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.zh.md +++ b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.zh.md @@ -40,6 +40,8 @@ Desktop Host 为保留 profile 提供共享 Web 插件管理器,并通过启 渲染进程使用 `nodeIntegration: false`、`contextIsolation: true` 和 `sandbox: true`。Preload 提供启动就绪与失败报告、原生目录选择、主题同步,以及 Windows 菜单和外观适配。它不暴露原始 `ipcRenderer`、文件系统访问、shell 命令或 pnpm 参数。Electron 菜单与原生对话框使用类型化中英文文案,并以英文回退;Windows 跟随主文档语言。共享 Web 插件管理器负责自身客户端文案。 +更新确认使用 shell 静态 origin,因为 Web Host 尚未就绪时也必须可用。其打包文档和资源保留与其他本地静态资源相同的方法和路径限制。 + ## 文件系统布局 ```text diff --git a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml index d67dd0c16f..bfe7ee764b 100644 --- a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.md -2026-08-28-subprocess-native-containment.md: 64fd59e13ea38d7f6e066d5dadec4be830c9c0af -2026-08-28-subprocess-native-containment.zh.md: 59e51c5a5c19f55058eb3881928d4f218a22a59c +2026-08-28-subprocess-native-containment.md: 88acee2d41fab878a0e50380cbb87eaece8e7296 +2026-08-28-subprocess-native-containment.zh.md: 53406f99531953a0330abf08be150da845f37aab diff --git a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.md b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.md index 64fd59e13e..88acee2d41 100644 --- a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.md +++ b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.md @@ -46,6 +46,8 @@ Linux falls back before target execution when the exact bootstrap, modern readab Normal Cordis disposal starts direct-result and range observation independently, requests termination, and waits for every owned range. Consumer teardown does not inspect an ordinary PID; it retains the original operation or startup error while attempting terminate and final wait, and preserves cleanup failures in the consumer's existing error order. A confirmed empty range permanently disables later signalling against stale identities. +Native Windows fixtures retain the same Job-owned termination and final wait on success and failure. A descendant PID is observation-only: issuing `taskkill` after its exit can terminate an unrelated process that has reused the number, including another concurrent test worker. + During a JavaScript-observable host exit, `LocalSubprocessRuntime` synchronously force-terminates every still-live handle without promises or timers. Linux sends the existing direct fallback kill and the exact scope kill; Windows kills the runner so its only Job handle closes; PTY fallback scans remain best effort. Per-handle failures are contained and do not change the host's exit result. Termination modes in which JavaScript cannot run remain outside this listener's guarantee. ## Existing decisions and supersession diff --git a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.zh.md b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.zh.md index 59e51c5a5c..53406f9953 100644 --- a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.zh.md +++ b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.zh.md @@ -46,6 +46,8 @@ selector 是 per-spawn locator 或 sentinel,不是凭据或持久格式。Linu 正常 Cordis dispose 会独立启动 direct-result 与 range observation、请求终止,并等待每个自有 range。消费方 teardown 不检查普通 PID;它会保留原始 operation 或 startup error,同时尝试 terminate 与 final wait,并按消费方既有错误顺序保留 cleanup failure。range 一旦被确认为空,就会永久禁止后续向陈旧 identity 发送信号。 +原生 Windows fixture 在成功和失败时都通过同一个 Job owner 请求终止并完成最终等待。后代 PID 仅用于观察:进程退出后再执行 `taskkill`,可能终止已复用该编号的无关进程,包括并发运行的其他测试 worker。 + 在 JavaScript 可观察的 host exit 期间,`LocalSubprocessRuntime` 会同步强制终止每个仍存活的句柄,不使用 Promise 或 timer。Linux 会发送既有 direct fallback kill 与准确 scope kill;Windows 会终止 runner,使其唯一 Job handle 关闭;PTY fallback 扫描仍是 best effort。每个句柄的失败相互隔离,也不改变宿主退出结果。JavaScript 无法运行的终止形态不属于该 listener 的保证。 ## Existing decisions and supersession diff --git a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml index 759741d3f1..7ac68f3f84 100644 --- a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md -2026-08-31-released-session-format-migrations.md: d566459af64f4177ed0135813e75aaf77480823c -2026-08-31-released-session-format-migrations.zh.md: f82b406117691197d808111f1c8aa4c722d4bab2 +2026-08-31-released-session-format-migrations.md: 5e885e110e9c720f2b72a374c9bcacd17d6addfe +2026-08-31-released-session-format-migrations.zh.md: a079ae8f47b4b941accf6c759f3d386117a6a548 diff --git a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md index d566459af6..5e885e110e 100644 --- a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md +++ b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md @@ -59,6 +59,7 @@ JSONL record → v0-to-v1 stage → v1-to-v2 stage → v2-to-v3 stage + → v3-to-v4 stage → current event collector ``` @@ -66,6 +67,8 @@ The chain contains no `flatMap`, spread expansion, intermediate event array, or ### Adjacent version ownership +The [V3-to-V4 specification](../../../../packages/session/session-format-v3-to-v4/README.md#v3-to-v4-specification) specifies parent catalog completion: it advances the header version, preserves admitted events and inherited cuts, and appends missing own catalog entries from child evidence. It reuses the frozen V3 codec from V2→V3. Generation-aware delivery validation prevents a historical acknowledgement from acquiring a current watermark meaning solely through the header change; earlier edges retain their own source-admission policies. + The [V2-to-V3 delivery guards](../../../../packages/session/session-format-v2-to-v3/README.md#delivery-guards) prevent a marker ignored in the source generation from becoming an active upload watermark merely because the header changes. Python release smoke checks generated logs against the source `SESSION_FORMAT_VERSION` independently of generation-neutral golden comparison, so coherent filenames and headers cannot conceal an outdated writer. The [V2-to-V3 README](../../../../packages/session/session-format-v2-to-v3/README.md#v2-to-v3-specification) is the single specification for that edge's transformations, preservation, and refusal; its separate [native admission section](../../../../packages/session/session-format-v2-to-v3/README.md#native-v3-admission) prevents current-only capabilities from being mistaken for historical transformations. The released V2 codec remains owned by V1→V2 and is reused, not copied. The [system-prompt](2026-09-02-system-prompt-as-surface-node.md), [PTC](../feature/2026-06-15-ptc.md), and [canonical-envelope](2026-09-06-v3-canonical-session-envelopes.md) notes retain their independent rationale, not duplicate conversion specifications. The [format-version cookbook](../../../../docs/cookbook/adding-a-session-format-version.md) owns package wiring, current consumers, snapshot successors, and validation commands. @@ -76,7 +79,7 @@ Preset renames cover the creation header and every selection event because the l A source inherited count can be unknown before EOF: V2 derives it from seed markers, and V1→V2 can change cardinality. The chain passes that absence to the next stage instead of fabricating a count. The [V2-to-V3 inheritance rules](../../../../packages/session/session-format-v2-to-v3/README.md#sequence-references) support this case; older stages that require a header-supplied count still refuse when it is absent. This permits seeded multi-hop restoration without retaining an intermediate artifact array. -The [version and release-status reference](../../../../docs/session-format-status.md) owns the published-format record and identifies the code’s writer authority. Released formats retain their semantics; committed generations remain byte-preserved during migration. A subsequent structural change requires the next adjacent edge under the [versioning rule](2026-08-10-session-log-version-mechanism.md), not an amendment to a released conversion. Ordinary event additions follow that rule’s required-event refusal mechanism rather than automatically allocating a version. A current-format file does not rerun its incoming migration; integration tests use isolated disposable homes and unchanged historical inputs. +The [version and release-status reference](../../../../docs/session-format-status.md) owns the published-format record and identifies the code’s writer authority. Released formats retain their semantics; committed generations remain byte-preserved during migration. A breaking change to the released target format requires the next adjacent edge under the [versioning rule](2026-08-10-session-log-version-mechanism.md). Incoming-converter fixes affect later historical conversions, not existing target files; the [cookbook](../../../../docs/cookbook/adding-a-session-format-version.md) owns compatibility review and alpha support policy. Ordinary event additions follow that rule’s required-event refusal mechanism rather than automatically allocating a version. Integration tests use isolated disposable homes and unchanged historical inputs. The [committed-corpus inventory](../../../../packages/test-support/llm-replay/tests/session-format-corpus-inventory.ts) identifies deliberately unsupported historical conversions by source path, generation, and exact refusal reason. Retaining those artifacts must not force chronology-changing migration or permit a blanket skip: every listed artifact must still raise the typed migration refusal, and unlisted artifacts must restore. Native current-generation fixtures cannot be classified as unsupported, because they do not traverse an incoming edge. Headerless test-harness protocol examples remain a separate explicit class. The corpus test checks source bytes after both successful and refused restoration; it does not rewrite historical evidence to satisfy the current reader. @@ -96,6 +99,8 @@ Current encoding is record based. The provider serializes about 1 MiB of plainte The shipped `lib/worker.cjs` bundles its JavaScript workspace dependencies so each fresh verifier avoids resolving and compiling their runtime module graph. This is safe because the Worker communicates through plain request/result messages and shares no service or class identity with its host. The Host build applies the existing TypeScript and Typert transforms; the Client pass skips this Node-only package instead of replacing its worker with untransformed source. Native add-ons remain external. Verification, scheduler admission, termination, and durable publication still complete before writable open returns. The built-worker smoke copies the package manifest and worker into an isolated temporary package with ambient module paths removed, accepts a valid generation, and rejects an incorrect event count. +The [browser preview packer](../../../../packages/experimental/webworker-packer/README.md) prepares current successors for bundled Session data in Node, using same-root direct-child descriptors as parent catalog evidence. The browser host does not implement `node:worker_threads`, so this preparation preserves both immutable fixture generations and runtime JSONL’s Worker verification requirement. + Preparation forwards cancellation through source reads and observes it at the existing approximately 500 ms Decode yield boundary. Once `publish()` starts, encode, Worker verification, and publication do not receive caller cancellation and run to settlement; write open checks its caller signal again afterward. A published generation is never rolled back. The Stage pipeline ends at one prepared current artifact. [Historical Session read preparation](2026-09-05-read-only-session-migration-preparation.md) defines how read open consumes that artifact immediately while write open performs encode, verification, and publication before returning append access. @@ -122,6 +127,44 @@ Existing write handles retain the process-local claim and kernel-backed cross-pr | Verification repeats on the main thread | At most two complete-generation Workers | Keeps verification CPU off the main thread | | Production and fixture migration use different APIs | Catalog `createRestore()` with explicit policies | One decoder/chain implementation | +### Parent catalog prerequisites + +V3→V4 completes parent child discovery from retained direct-child headers and own descriptors. Storage supplies compact descriptor evidence to the catalog assembly, which binds it into the V3→V4 stage factory; the Stage waits for the parent's final inherited cut before validating catalog payloads and deriving available own discovery facts. Nested seed markers discard inherited catalog candidates without interpreting their payloads. An existing catalog entry survives an unavailable descriptor, including a child that failed before its first step. Descriptor v1 denotes continuable mode; v2/v3 explicitly record mode. Available unambiguous discovery fields must agree with the parent; absent entries require one supported descriptor. Missing, unsupported, or multiple descriptors preserve the logs without backfilling that child, as recorded in [incomplete child evidence](../bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.md). JSONL rechecks related membership and source revisions when preparing, reusing, and publishing. An unsupported generation or unreadable header elsewhere in that scan refuses migration because it cannot prove unrelatedness. Source drift invalidates preparation; read open retries once automatically, while write open refuses publication. Diagnostics retain the offending child path and distinguish unsupported migration evidence from malformed child data. The storage decoder classifies physical JSON and compression failures before the collector adds child context; filesystem reads and cancellation keep their original errors. The V0–V3-only catalog avoids recursive child migration. Current V4 reads skip that scan but apply the same own-catalog field, uniqueness, and current delivery ownership checks as strict restoration. See the [format specification](../../../../packages/session/session-format-v3-to-v4/README.md). + +Raw parent/child migration tests retain 24 historical creation-time conflicts as rejection evidence. Detached controls align only the child creation time and prove event-preserving restoration, including a published child without a descriptor. Headless/ACP and SDK snapshot adapters validate live parent/child clocks before normalization and preserve their equality during refresh; committed predecessor generations remain unchanged. + +Historical public revisions combine the parent’s physical revision with a fingerprint of every selected canonical path and its filesystem revision. Parent-only tokens cannot identify catalog changes supplied by children; a root fingerprint preserves metadata-only `stat`/`list` and includes unreadable or unsupported members without a new persistent index. Unrelated changes also invalidate historical caches, and obtaining the token costs a root scan. Current tokens stay file-local. The preparation memo keeps physical parent revisions and separately validates child membership and revisions. + +The generic format interfaces carry only the artifact being restored. Parent-specific catalog assembly replaces the V3→V4 declaration with a closure over the collected child evidence; it reuses the generated codec, migration, and validation inventory. The assembly compiles one short migration chain per parent preparation, with independent stage state per restore. Binding at assembly keeps child evidence out of generic restore options and stage inputs without moving discovery or source revalidation into the migration. Static header and native current reads need no child evidence; an unbound historical body restore refuses rather than assuming an empty child set. + + +### Catalog scan measurements + +The package-local [diagnostic](../../../../packages/session/session-persistence-jsonl/tests/catalog-migration.perf.ts) measures one raw V3 parent, four direct children with 1,000 events each, and 0/100/1,000 unrelated header-only V3 Sessions. Each sample creates its own temporary corpus and Cordis context in a fresh process, runs stat → cold read → memo read → write publication → current warm read, and disposes the context and files. It uses built workspace exports under plain Node; fixture creation is outside the measured intervals. These are filesystem-cache-warm observations after fixture creation, not disk-cold latency or a performance gate. + +On macOS arm64 with Node v26.0.0, all three samples per size are below in milliseconds. Read-only opens do not publish: membership scanning remains proportional to corpus size even when decoding is memoized. The 1,000-unrelated medians are 84.14 ms for stat, 237.97 ms for cold read, 110.98 ms for memo read, 268.46 ms for publication, and 0.41 ms for the same-process current read. These measurements document the cost; they establish no speedup claim or cross-host threshold. + +| Unrelated Sessions | Historical stat | Cold read | Memo read | Publish | Current warm read | +|---:|---:|---:|---:|---:|---:| +| 0 | 5.17 | 19.00 | 1.36 | 42.88 | 0.47 | +| 0 | 3.30 | 14.87 | 1.45 | 35.75 | 0.41 | +| 0 | 3.18 | 16.71 | 1.50 | 34.51 | 0.47 | +| 100 | 29.44 | 77.48 | 17.01 | 60.66 | 0.43 | +| 100 | 12.42 | 42.71 | 13.69 | 60.19 | 0.43 | +| 100 | 11.19 | 41.06 | 12.61 | 57.18 | 0.39 | +| 1000 | 84.14 | 237.97 | 109.86 | 284.96 | 0.48 | +| 1000 | 99.41 | 259.88 | 123.50 | 268.46 | 0.41 | +| 1000 | 75.40 | 236.64 | 110.98 | 247.69 | 0.39 | + +Run from the repository root after building the runtime: + +```sh +pnpm run build:lib:host +cd packages/session/session-persistence-jsonl +node --input-type=module -e 'import { build } from "tsdown"; await build({ config: false, entry: ["tests/catalog-migration.perf.ts"], outDir: ".artifacts/perf", tsconfig: false, dts: false, deps: { neverBundle: [/^@deepseek-ai\//], onlyBundle: false } })' +node .artifacts/perf/catalog-migration.perf.mjs +``` + ## Verification The migration specification requires evidence for transformations, preservation, and refusal separately. Direct-edge and native V3 tests cannot establish seeded multi-hop publication: preceding assistant-stream folding changes source coordinates before V3 inserts system events. Tests through the real catalog and JSONL provider therefore need raw and compressed V0/V1 inputs, mapped references and inherited cuts, publish/reopen equivalence, unchanged predecessor bytes, and no intermediate generations. Coverage percentages alone cannot prove those cross-stage relationships; combined assertions must compare the resulting history and refusal effects. diff --git a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md index f82b406117..a079ae8f47 100644 --- a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md +++ b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md @@ -59,6 +59,7 @@ JSONL record → v0-to-v1 stage → v1-to-v2 stage → v2-to-v3 stage + → v3-to-v4 stage → current event collector ``` @@ -66,6 +67,8 @@ Chain 中不存在 `flatMap`、spread expansion、中间 event array 或 schedul ### 相邻版本所有权 +[V3 到 V4 规范](../../../../packages/session/session-format-v3-to-v4/README.zh.md#v3-to-v4-specification)规定父目录补全:它推进 header 版本,保留已接纳的事件与继承切点,并根据子 Session 证据追加缺失的自身目录记录。它复用 V2→V3 中冻结的 V3 codec。按 generation 校验 delivery 可防止历史确认仅因 header 变化而获得当前水位含义;更早的 migration edge 保留各自的来源准入策略。 + [V2 到 V3 投递保护](../../../../packages/session/session-format-v2-to-v3/README.zh.md#delivery-guards)防止源代中被忽略的标记仅因头部变化就成为有效上传水位。Python 发布冒烟测试独立于跨代 golden 比较,按源代码中的 `SESSION_FORMAT_VERSION` 检查生成日志,因此文件名与 header 自洽不能掩盖过期 writer。 [V2 到 V3 README](../../../../packages/session/session-format-v2-to-v3/README.zh.md#v2-to-v3-specification)是该迁移边转换、保留与拒绝规则的单一规范真源;单列的[原生准入章节](../../../../packages/session/session-format-v2-to-v3/README.zh.md#native-v3-admission)避免将仅当前版本支持的能力误认为历史转换。已发布 V2 codec 仍归 V1→V2 所有,并被复用而非复制。[系统提示词](2026-09-02-system-prompt-as-surface-node.zh.md)、[PTC](../feature/2026-06-15-ptc.zh.md)和[规范信封](2026-09-06-v3-canonical-session-envelopes.zh.md)记录保留各自独立依据,而非重复转换规范。[格式版本实操手册](../../../../docs/cookbook/adding-a-session-format-version.zh.md)负责包接线、当前消费方、快照后继代际与验证命令。 @@ -76,7 +79,7 @@ Chain 中不存在 `flatMap`、spread expansion、中间 event array 或 schedul 源继承数量在 EOF 前可能未知:V2 从种子标记推导它,而 V1→V2 可以改变事件数量。迁移链将这种缺失传递给下一个 Stage,而不伪造数量。[V2 到 V3 继承规则](../../../../packages/session/session-format-v2-to-v3/README.zh.md#sequence-references)支持此情况;需要 header 提供数量的旧 Stage 仍在数量缺失时拒绝。这使有种子的多跳恢复无需保留中间产物数组。 -[版本与发布状态参考](../../../../docs/session-format-status.zh.md)拥有已发布格式记录,并指明代码中的写入器真源。已发布格式保留其语义;迁移期间已提交代际的字节保持不变。后续结构性变更必须按[版本规则](2026-08-10-session-log-version-mechanism.zh.md)添加下一条相邻迁移边,而非修改已发布转换。普通事件新增遵循该规则的必需事件拒绝机制,而非自动分配版本。当前格式文件不会重新执行入边迁移;集成测试使用隔离、可丢弃的 home 和未变更的历史输入。 +[版本与发布状态参考](../../../../docs/session-format-status.zh.md)拥有已发布格式记录,并指明代码中的写入器真源。已发布格式保留其语义;迁移期间已提交代际的字节保持不变。对已发布目标格式的破坏性变更必须按[版本规则](2026-08-10-session-log-version-mechanism.zh.md)添加下一条相邻迁移边。传入转换器修复影响之后的历史转换,不影响已有目标格式文件;[cookbook](../../../../docs/cookbook/adding-a-session-format-version.zh.md)拥有兼容性评审和 alpha 支持政策。普通事件新增遵循该规则的必需事件拒绝机制,而非自动分配版本。集成测试使用隔离、可丢弃的 home 和未变更的历史输入。 [已提交语料清单](../../../../packages/test-support/llm-replay/tests/session-format-corpus-inventory.ts) 按源路径、代际与精确拒绝原因标识有意不支持的历史转换。保留这些产物不能迫使迁移改变时序,也不能允许统一跳过:每个清单中的产物仍必须抛出类型化迁移拒绝,未列入的产物必须还原。原生当前代际 fixture 不经过入边,因此不能被归为不支持。没有版本 header 的测试框架协议示例保持为独立的显式类别。语料测试在还原成功和拒绝后都检查源字节;它不通过改写历史证据来满足当前 reader。 @@ -96,6 +99,8 @@ Current encode 以单条 record 为单位。Provider 在主线程每个 slice 发布的 `lib/worker.cjs` 将 JavaScript workspace 依赖一起打包,使每个新 verifier 无需解析并编译它们的运行时模块图。Worker 只通过普通 request/result 消息通信,与 host 不共享 service 或 class identity,因此可以这样处理。Host build 应用现有 TypeScript 与 Typert 转换;Client pass 跳过这个 Node-only package,不会用未经转换的源代码覆盖 worker。Native add-on 保持 external。Verification、scheduler admission、termination 与 durable publication 仍在 writable open 返回前完成。Built-worker 冒烟测试把 package manifest 与 worker 复制到隔离的临时 package,移除环境中的模块搜索路径,接受有效 generation,并拒绝错误的 event count。 +[浏览器 preview 打包器](../../../../packages/experimental/webworker-packer/README.zh.md)在 Node 中为随包 Session 数据准备当前代际后继,并使用同一根目录中直属子 Session 的 descriptor 作为父目录证据。浏览器 host 未实现 `node:worker_threads`,因此打包阶段的准备同时保留不可变 fixture 代际与运行时 JSONL 的 Worker 校验要求。 + Preparation 会把 cancellation 传给 source read,并在现有的约 500 ms Decode yield 边界观察它。`publish()` 一旦开始,encode、Worker verification 与 publication 不接收 caller cancellation,并运行到终态;write open 会在之后再次检查 caller signal。已经发布的 generation 绝不会回滚。 Stage pipeline 终止于一份 prepared current artifact。[历史 Session 只读迁移准备](2026-09-05-read-only-session-migration-preparation.zh.md)定义 read open 如何立即消费该 artifact,以及 write open 如何在返回 append 权限前完成 encode、verification 与 publication。 @@ -122,6 +127,44 @@ POSIX publication 使用 hard-link creation 加目录 sync;Windows 使用 no-o | 主线程重复执行完整 verification | 最多两个 complete-generation Worker | Verification CPU 不占用主线程 | | Production 与 fixture 使用不同 migration API | Catalog `createRestore()` 加显式 policy | 只保留一套 decoder/chain 实现 | +### 父目录前置事实 + +V3→V4 使用保留的直属子 Session header 和自身 descriptor 补齐父 Session 的子代理发现记录。存储将紧凑的 descriptor 证据提供给 catalog 组装处,由其绑定到 V3→V4 stage 工厂;Stage 等待父 Session 的最终继承截点确定后,才校验目录 payload 并导出可获得的自身发现事实。嵌套的 seed 标记丢弃继承目录候选,不解释其 payload。已有目录记录允许 descriptor 不可用,包括在首次 step 之前失败的子 Session。Descriptor v1 表示 continuable 模式;v2/v3 显式记录模式。可获得且明确的发现字段必须与父目录一致;缺失记录要求一个受支持的 descriptor。Descriptor 缺失、版本不受支持或存在多个时,保留日志但不补填对应子 Session,理由见[不完整子目录证据](../bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.zh.md)。JSONL 在准备、复用和发布时重新检查关联成员与来源修订。扫描中其他任何不支持代际或不可读 header 都会拒绝迁移,因为无法证明它与父 Session 无关。来源变化使准备缓存失效;只读打开自动重试一次,写打开则拒绝发布。诊断保留出错子日志的路径,并区分不支持的迁移证据与畸形子数据。存储解码器先将物理 JSON 与压缩错误归类,再由收集器补充子日志信息;文件系统读取与取消保留原始错误。仅支持 V0–V3 的目录避免递归迁移子 Session。当前 V4 读取跳过该扫描,但会执行与严格恢复相同的自身目录字段、唯一性及当前投递归属检查。见[格式规范](../../../../packages/session/session-format-v3-to-v4/README.zh.md)。 + +原始父子迁移测试保留 24 个历史创建时间冲突作为拒绝证据。独立的内存对照只对齐子创建时间,证明恢复保留事件,包括已发布但没有 descriptor 的子 Session。Headless/ACP 与 SDK 快照适配器在规范化之前校验实时父子时钟,并在刷新时保持两者相等;已提交的前代文件保持不变。 + +历史格式的公开修订号组合父日志物理修订号与每个所选规范路径及其文件系统修订号的指纹。仅父日志令牌无法标识子日志提供的目录变化;全库指纹让 `stat`/`list` 保持只读元数据,也纳入不可读或不支持的成员,无需新增持久化索引。无关变化也会使历史缓存失效,获取令牌需要扫描根目录。当前格式令牌仍只取决于自身文件。准备缓存保留父日志物理修订号,并独立校验子成员集合与修订。 + +通用格式接口只传递正在恢复的 artifact。每个父 Session 的 catalog 组装将 V3→V4 声明替换为捕获已收集子 Session 证据的闭包,并复用生成的 codec、迁移与校验清单。每次父 Session 准备只编译一条短迁移链,每次恢复拥有独立的 stage 状态。在组装处绑定证据,使通用恢复选项和 stage 输入不必携带子 Session 证据,同时保留存储对发现与来源重验的所有权。静态 header 和原生当前格式读取不需要子 Session 证据;未绑定的历史正文恢复会拒绝,不会假定子 Session 集合为空。 + + +### 目录扫描测量 + +包内[诊断脚本](../../../../packages/session/session-persistence-jsonl/tests/catalog-migration.perf.ts)测量一个原始 V3 父日志、四个各有 1,000 条事件的直属子日志,以及 0/100/1,000 个只有 header 的无关 V3 Session。每个样本在新进程中创建独立临时日志库与 Cordis 上下文,按 stat → 冷读 → 缓存读取 → 写入发布 → 当前格式热读顺序执行,最后释放上下文并删除文件。脚本在普通 Node 下使用已构建的工作区导出;创建夹具不计入测量区间。这些结果是夹具创建后的文件系统缓存热态观察,不代表磁盘冷读延迟,也不是性能门禁。 + +以下为 macOS arm64、Node v26.0.0 下各规模的全部三个样本,单位为毫秒。只读打开不发布后继:即使解码结果已缓存,成员扫描仍与日志库规模成正比。1,000 个无关日志时,中位数分别为 stat 84.14 ms、冷读 237.97 ms、缓存读取 110.98 ms、发布 268.46 ms,以及同进程当前格式读取 0.41 ms。这些测量记录成本,不证明性能提升,也不设跨主机阈值。 + +| 无关 Session | 历史 stat | 冷读 | 缓存读取 | 发布 | 当前格式热读 | +|---:|---:|---:|---:|---:|---:| +| 0 | 5.17 | 19.00 | 1.36 | 42.88 | 0.47 | +| 0 | 3.30 | 14.87 | 1.45 | 35.75 | 0.41 | +| 0 | 3.18 | 16.71 | 1.50 | 34.51 | 0.47 | +| 100 | 29.44 | 77.48 | 17.01 | 60.66 | 0.43 | +| 100 | 12.42 | 42.71 | 13.69 | 60.19 | 0.43 | +| 100 | 11.19 | 41.06 | 12.61 | 57.18 | 0.39 | +| 1000 | 84.14 | 237.97 | 109.86 | 284.96 | 0.48 | +| 1000 | 99.41 | 259.88 | 123.50 | 268.46 | 0.41 | +| 1000 | 75.40 | 236.64 | 110.98 | 247.69 | 0.39 | + +在仓库根目录构建运行时后执行: + +```sh +pnpm run build:lib:host +cd packages/session/session-persistence-jsonl +node --input-type=module -e 'import { build } from "tsdown"; await build({ config: false, entry: ["tests/catalog-migration.perf.ts"], outDir: ".artifacts/perf", tsconfig: false, dts: false, deps: { neverBundle: [/^@deepseek-ai\//], onlyBundle: false } })' +node .artifacts/perf/catalog-migration.perf.mjs +``` + ## 验证 迁移规范要求分别提供转换、保留与拒绝的证据。直接迁移边和原生 V3 测试不能证明有种子的多跳发布:前代 assistant 流折叠会在 V3 插入系统事件前改变源坐标。因此,经过真实目录与 JSONL 提供方的测试需要原始及压缩的 V0/V1 输入、映射后的引用和继承切点、发布/重新打开等价性、前代字节不变,以及不产生中间代。覆盖率百分比本身不能证明这些跨阶段关系;组合断言必须比较结果历史与拒绝效果。 diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml index c09aaa9dcb..59e3f84862 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md -2026-09-01-parent-owned-subagent-catalog.md: 20e2dd035b41612592e7baeb55f89322dff02848 -2026-09-01-parent-owned-subagent-catalog.zh.md: 6ec33e8be8d4373ba98a9934178a67e207ffb0bb +2026-09-01-parent-owned-subagent-catalog.md: 536ec33148bd675a974622b98ee23de812691dc0 +2026-09-01-parent-owned-subagent-catalog.zh.md: ec78ff9e4b7d54a7309baf21c383ec5ff83a19c8 diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md index 20e2dd035b..536ec33148 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md +++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md @@ -44,6 +44,6 @@ Current-writer snapshot expectations include catalog facts even when replay inpu ## Consequences -Session observations and client snapshots expose the direct-child list through `projections.values.subagentCatalog`. The projection change feed publishes a complete list when catalog state changes. Each view costs O(D), so D creations can incur O(D²) cumulative view work; this follows the existing projection mechanism. Direct-child and descendant listing still use the Session corpus and child identity projection. +Session observations and client snapshots expose the direct-child list through `projections.values.subagentCatalog`. The projection change feed publishes a complete list when catalog state changes. Each view costs O(D), so D creations can incur O(D²) cumulative view work; this follows the existing projection mechanism. `listChildren()` reads the parent projection through one live-preferred Session observation; descendant listing uses the Session corpus and child identity projection. [Web projection consumption](../simplification/2026-09-08-web-subagent-catalog-projections.md) owns browser loading and synchronization. -Backends that do not know the required event refuse the log under the existing Session event mechanism. Catalog projection does not reconstruct missing parent facts by scanning old child logs. +[Creation metadata exclusion](../simplification/2026-09-16-subagent-catalog-membership-only.md) records why model configuration is absent from catalog facts. diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md index 6ec33e8be8..ec78ff9e4b 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md @@ -44,6 +44,6 @@ snapshot normalizer 会把 `childCreatedAt` 归零,因为它来自 process clo ## 后果 -Session 观察和客户端快照通过 `projections.values.subagentCatalog` 暴露直接子级列表。目录状态变化时,projection 变更通知发布完整列表。每次视图计算成本为 O(D),因此 D 次创建的累计视图工作量可能为 O(D²);这沿用既有 projection 机制。直接子级和后代列表仍使用 Session 语料库与子级身份 projection。 +Session observation 与 client snapshot 通过 `projections.values.subagentCatalog` 暴露直接子级列表。目录状态变化时,projection change feed 发布完整列表。每次 view 的成本为 O(D),因此 D 次创建可能累计产生 O(D²) 的 view 工作量;这沿用现有 projection 机制。`listChildren()` 通过一次 live-preferred Session observation 读取父 projection;后代枚举使用 Session 语料库与子身份 projection。[Web projection 消费决策](../simplification/2026-09-08-web-subagent-catalog-projections.zh.md) 说明浏览器加载与同步。 -不认识该 required event 的 backend 会按既有 Session event 机制拒绝日志。目录投影不通过扫描旧子级日志来重建缺失的父级事实。 +[创建元数据排除决策](../simplification/2026-09-16-subagent-catalog-membership-only.zh.md) 说明目录事实为何不包含模型配置。 diff --git a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml index a3a50d38ef..e834c8bf6f 100644 --- a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.md -2026-09-06-v3-canonical-session-envelopes.md: 17ec331cc1ea21f31d0b51eab86d22725b6deef8 -2026-09-06-v3-canonical-session-envelopes.zh.md: a18bb3b4d71c164e3fba7288cc686a1cb7c7b4df +2026-09-06-v3-canonical-session-envelopes.md: 68d4386b9e06025fd44d6d9054a95fb51ec8bc3e +2026-09-06-v3-canonical-session-envelopes.zh.md: d3bfc17fa263f8edb0b6f73ce59c626d772dbc1e diff --git a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.md b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.md index 17ec331cc1..68d4386b9e 100644 --- a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.md +++ b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.md @@ -14,7 +14,7 @@ Session format V3 uses one canonical event envelope. Every `system/message`, `us `SurfaceOp` is exactly `'append'` or `{ op: 'replace', startSeq, endSeq }`, with `SessionSeq` endpoints and no aliases or extra keys. Both endpoints precede the replacing event and identify an inclusive span in current surface order, not numeric sequence order. Session acceptance additionally verifies current membership, ordered endpoints, complete cited coverage, and content-only single-node tool-result replacement. Compaction payload fields such as `shadowedRange.start/end` and fold-result fields retain their own names; this is not a recursive payload rename. -Current acceptance rejects every `request/header.header.system` and exactly empty `tools: []` or `adapterDefaults: {}`. System prompts belong to `system/message`; `request/header` remains the non-history request snapshot. Writers omit the two empty optionals. Whitespace-only system content, `config.stop: []`, nested header/source/data extras, and nested tool schema values remain intact. A `tool/result` with `data.error` requires `message.content[0].isError === true`; a failed result need not carry error identity. Neither current reads nor migration infer an error outcome from contradictory metadata. +Current acceptance rejects every `request/header.header.system` and exactly empty `tools: []` or `adapterDefaults: {}`. System prompts belong to `system/message`; `request/header` remains the non-history request snapshot. Writers omit the two empty optionals. Whitespace-only system content, `config.stop: []`, nested header/source/data extras, and nested tool schema values remain intact. A `tool/result` with `data.error` requires `message.isError === true`; a failed result need not carry error identity. Neither current reads nor migration infer an error outcome from contradictory metadata. ### Validation ownership diff --git a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.zh.md b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.zh.md index a18bb3b4d7..d3bfc17fa2 100644 --- a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.zh.md @@ -14,7 +14,7 @@ Session 格式 V3 使用一种规范事件信封。每个 `system/message`、`us `SurfaceOp` 恰好为 `'append'` 或 `{ op: 'replace', startSeq, endSeq }`,端点使用 `SessionSeq`,不接受别名或额外键。两个端点都早于替换事件,并按当前 surface 顺序而非数值序号顺序标识闭区间。Session 接纳还验证当前成员关系、端点顺序、完整引用覆盖与仅修改内容的单节点工具结果替换。`shadowedRange.start/end` 等压缩(compaction)载荷字段与折叠结果字段保留各自名称;这不是对载荷进行递归重命名。 -当前接纳拒绝任何 `request/header.header.system` 以及恰好为空的 `tools: []` 或 `adapterDefaults: {}`。系统提示词属于 `system/message`;`request/header` 仍是请求非历史状态的快照。写入方省略两个空可选字段。仅含空白的系统内容、`config.stop: []`、嵌套 header/source/data 扩展与嵌套工具 schema 值保持原样。带有 `data.error` 的 `tool/result` 要求 `message.content[0].isError === true`;失败结果不必携带错误身份。当前读取与迁移均不会根据矛盾元数据推断错误结果。 +当前接纳拒绝任何 `request/header.header.system` 以及恰好为空的 `tools: []` 或 `adapterDefaults: {}`。系统提示词属于 `system/message`;`request/header` 仍是请求非历史状态的快照。写入方省略两个空可选字段。仅含空白的系统内容、`config.stop: []`、嵌套 header/source/data 扩展与嵌套工具 schema 值保持原样。带有 `data.error` 的 `tool/result` 要求 `message.isError === true`;失败结果不必携带错误身份。当前读取与迁移均不会根据矛盾元数据推断错误结果。 ### 校验所有权 diff --git a/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml new file mode 100644 index 0000000000..1514b7c6d3 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.md +2026-09-09-producer-owned-message-sources.md: 83f8cb9368b516b7b6fde8717f9e5f8e9d4f7d4e +2026-09-09-producer-owned-message-sources.zh.md: f5cdfc48286f7b92883938c8e316a7751580f52c diff --git a/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.md b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.md new file mode 100644 index 0000000000..83f8cb9368 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.md @@ -0,0 +1,33 @@ +# Agent Note: Producer-owned message sources at the V4 edge + +Status: implemented + +English | [中文](2026-09-09-producer-owned-message-sources.zh.md) + +## Problem + +Released V3 plugin attribution uses the shared wrapper `{ kind: 'plugin', plugin: '' }` plus the producer's context-form fields, so consumers had to treat one synthetic kind specially instead of switching on the producer identity. Once tool results became first-class tool-role messages and the current generation moved to V4, the format layer also had to keep reading released V3 files whose rows still carry the wrapper. + +## Decision + +Message sources are producer-owned: `kind` identifies the producer, with declarations contributed through `MessageSourceMap`. The V3-to-V4 migration uses its fixed producer table: `@deepseek-ai/dsh-system-prompt` becomes `system-prompt` for system-role messages and `runtime-context` otherwise; `compact` becomes `compact-checkpoint`; `tools-code-mode` and `tools-ptc` become `ptc-mode`; `dsh-compaction-basic` becomes `compact-basic`; known same-name producers retain their kind. Unknown plugin names receive `plugin:` before the complete original name, while direct source kinds retain their original names. The prefix keeps a plugin named `user` separate from the human-user kind; this edge leaves direct attribution unchanged. Original context-form fields and other own JSON metadata survive; only the old wrapper's identity fields receive their specified conversion. Rename lookup uses own keys, so `__proto__` and `constructor` remain data. + +Native V4 source admission rejects the retired `kind: 'plugin'` wrapper in every declared durable message slot, including inbox and title-request messages. This refusal applies before recoverable scanning can discard a suffix. Complete source-slot validation runs in the shared known-event pass used by both the format catalog and native JSONL scanner, before either exposes a restored artifact or handle. Unknown nonempty attribution kinds and their extra JSON fields survive without their producer installed. Native compaction and title relationship checks use the producer kinds directly; the [mandatory validation decision](2026-09-17-native-v4-read-validation.md) owns common lifecycle rules. + +The source rewrite is owned by the V3-to-V4 migration stage and runs once while historical events become V4 events. The current V4 codec retains only the released physical framing and native V4 admission; it never sends a V4 row through the released V3 validator and has no source-conversion view in its encode, decode, restore, or row-admission paths. + +Recorded current V4 fixtures and writer, notification, and stream-json sidecars are producer-owned; released V2/V3 fixtures and sidecars keep plugin attribution and convert at read time through the migration. The [released session-format migrations](2026-08-31-released-session-format-migrations.md) note owns the versioning rules this edge follows. + +The [source-attribution policy](2026-09-17-persistence-attribution-policy.md) distinguishes durable source declarations from request-only user inputs and records the narrowly scoped compatibility promise for new attribution kinds. Frozen migration rules retain historical producer kinds even when no active producer declares them. + +## Alternatives considered + +**Keep the released plugin wrapper as the current shape.** Consumers would keep switching on one synthetic kind and the producer identity stays an untyped string; the current semantic validators would keep a second, unreleased source vocabulary. + +**Rewrite released rows only at scan time instead of migrating them.** Scan admission is deliberately shape-only and refuses, never repairs; a scan-time rewrite would blur released generations with current rows and leave the current artifact with version-inappropriate source identities. + +**Reject plugin-kind rows as ordinary corruption in the scanner.** That would let a stale released row silently truncate a current Session instead of surfacing a refusal, and would misclassify rows that full decoding still needs to diagnose. + +## Consequences + +The recorded corpus for this migration applies the frozen rename table, while current-generation validation consumes producer-owned kinds directly. Web context labels render the producer kind (`runtime-context`) instead of the released plugin string. The shared rewriter reports malformed released sources as `SessionFormatError`, so a malformed historical source is a migration refusal rather than a silent payload loss. diff --git a/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.zh.md b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.zh.md new file mode 100644 index 0000000000..f5cdfc4828 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.zh.md @@ -0,0 +1,33 @@ +# Agent Note: V4 边缘上的生产者归属消息源 + +Status: implemented + +[English](2026-09-09-producer-owned-message-sources.md) | 中文 + +## Problem + +已发布 V3 的插件归属使用共享包装 `{ kind: 'plugin', plugin: '' }` 外加生产者的上下文形态字段,消费方因此必须特殊对待一个合成 kind,而不是直接按生产者身份切换。工具结果成为一等 tool-role 消息、当前世代进入 V4 之后,格式层还必须继续读取仍带包装的已发布 V3 文件。 + +## Decision + +消息源由生产者拥有:`kind` 标识生产者,各方通过 `MessageSourceMap` 提供声明。V3-to-V4 迁移使用固定生产者表:`@deepseek-ai/dsh-system-prompt` 在 system-role 消息上变成 `system-prompt`,否则变成 `runtime-context`;`compact` 变成 `compact-checkpoint`;`tools-code-mode` 与 `tools-ptc` 变成 `ptc-mode`;`dsh-compaction-basic` 变成 `compact-basic`;已知同名生产者保留 kind。未知插件名在完整原名之前添加 `plugin:`,直接 source kind 则保留原名。该前缀将名为 `user` 的插件与人类用户 kind 区分开;本边保持直接归属不变。原上下文形态字段及其他自有 JSON 元数据保留;只有旧包装的身份字段执行指定转换。重命名查找使用自有键,因此 `__proto__` 和 `constructor` 仍是数据。 + +原生 V4 消息源准入在每个声明的持久化消息槽位拒绝退役的 `kind: 'plugin'` 包装,包括 inbox 和标题请求消息。可恢复扫描丢弃后缀之前就会执行此拒绝。完整消息源槽位校验在格式目录和原生 JSONL 扫描器共用的已知事件校验中执行,先于两者公开恢复产物或句柄。即使生产者未安装,未知的非空归属 kind 及额外 JSON 字段仍原样保留。原生压缩和标题关系校验直接使用生产者 kind;[强制校验决策](2026-09-17-native-v4-read-validation.zh.md)负责通用生命周期规则。 + +来源重写由 V3 到 V4 迁移 Stage 负责,在历史事件转换为 V4 事件时只执行一次。当前 V4 编解码器只保留已发布的物理分帧和原生 V4 准入;它不会让 V4 行进入已发布 V3 校验器,编码、解码、恢复和行准入路径也没有来源转换视图。 + +录制的当前 V4 fixtures 与 writer、notification、stream-json 侧车是生产者归属的;已发布的 V2/V3fixtures 与侧车保留 plugin 归属,读取时经迁移转换。[released session-format migrations](2026-08-31-released-session-format-migrations.zh.md)笔记拥有本边所遵循的版本规则。 + +[消息源归属策略](2026-09-17-persistence-attribution-policy.zh.md)区分持久化 source 声明与仅用于请求的 user 输入,并记录新增归属 kind 的受限兼容性承诺。即使没有活动生产者声明,冻结迁移规则仍保留历史生产者 kind。 + +## Alternatives considered + +**保留 released plugin 包装作为当前形态。** 消费方将继续特殊对待一个合成 kind,生产者身份仍是无类型字符串;当前语义校验器也会保留第二套非发布的消息源词汇。 + +**只在扫描时重写 released 行而不是迁移它们。** 扫描准入刻意只查形态并拒绝、从不修复;扫描时重写会模糊 released 世代与当前行的界限,使当前产物保留与版本不符的来源身份。 + +**在 scanner 中把 plugin-kind 行当作普通损坏拒绝。** 这会让过期的 released 行静默截断当前 Session,而不是给出拒绝;也会把完整解码仍需要诊断的行错误分类。 + +## Consequences + +本迁移的记录语料库应用冻结重命名表,而当前代校验器直接消费生产者自有 kind。Web 上下文标签渲染生产者 kind(`runtime-context`)而不是 released plugin 字符串。共享重写器将畸形历史来源报告为 `SessionFormatError`,因此迁移会拒绝它,而不会静默丢失载荷。 diff --git a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml index 3a9f8ed124..6953db3edf 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-image-offload-events.md -2026-09-10-image-offload-events.md: f540dc98cee8daf3e360b14234a2ac21d0f53aab -2026-09-10-image-offload-events.zh.md: 868fca59ba5fc1941de752127f61b091aedb234f +2026-09-10-image-offload-events.md: e80c4ae17b148d9eb46517b92111a8d768160def +2026-09-10-image-offload-events.zh.md: 2aa2b8b1fbffd117b5d716aba28755a02a155bb8 diff --git a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.md b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.md index f540dc98ce..e80c4ae17b 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.md +++ b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.md @@ -14,7 +14,7 @@ A request can exceed an image-capable route's byte or image-count budget. Recomp Summary requests bypass the agent error waterfall. `dsh-compaction-basic` preserves the full `LlmFailure`, checks cancellation and selection stability, and dispatches synchronous `compaction/summary-error` with the selected event seqs. The same image-offload plugin records omissions only within that selection. Synchronous recovery keeps the stability check and decision adjacent. The backend then re-derives input and pricing, including the shrink baseline. Each retry requires additional omitted occurrences; exhaustion delegates the failure. A later summary failure or cancellation preserves any recorded omissions, so command errors do not claim the conversation is unchanged. -The event payload is `{ targets: [{ seq, imageIndexes }] }`. Each target identifies a current `user/message` or `tool/result` node. Its strictly increasing, zero-based indexes enumerate every image in depth-first content order, including nested tool results and previously omitted images. Equal attachment ids remain distinct occurrences. Exact selections remain unambiguous after positional replacements reorder the surface; an attachment id or a raw-log prefix cannot identify the selected set. +The event payload is `{ targets: [{ seq, imageIndexes }] }`. Each target identifies a current `user/message` or `tool/result` node. Its strictly increasing, zero-based indexes enumerate every image in depth-first content order, including tool-role result content and previously omitted images. Equal attachment ids remain distinct occurrences. Exact selections remain unambiguous after positional replacements reorder the surface; an attachment id or a raw-log prefix cannot identify the selected set. The event has no `surfaceOp`. It neither creates a message nor replaces a message node. The plugin's pure projection validates all targets before Session commits the event and rejects missing or shadowed nodes, output images, duplicate targets, invalid indexes, and already omitted occurrences. Reconstruction derives immutable message copies with `ImageBlock.offloaded: true` at the recorded positions. Original events, message ids, sources, and unaffected blocks remain unchanged. Resume, fork, and replay apply the same selections from the log. diff --git a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.zh.md b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.zh.md index 868fca59ba..2aa2b8b1fb 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.zh.md @@ -14,7 +14,7 @@ Status: implemented 摘要请求不经过 agent 错误 waterfall。`dsh-compaction-basic` 保留完整的 `LlmFailure`,检查取消和选区稳定性,再携带所选事件序号触发同步的 `compaction/summary-error`。同一个图片省略插件只在选区内记录省略。同步恢复使稳定性检查与决策相邻执行。后端随后重新派生输入并计价,包括判断摘要是否缩短输入的基准。每次重试都必须继续省略图片,无图可省略时委派失败。后续摘要失败或取消仍保留已经记录的省略,因此命令错误不声称会话未变。 -事件载荷为 `{ targets: [{ seq, imageIndexes }] }`。每个目标指向当前的 `user/message` 或 `tool/result` 节点。索引从零开始且严格递增,按内容深度优先顺序枚举所有图片,包括嵌套工具结果和先前省略的图片。相同附件 ID 的多次出现分别计数。位置替换改变 surface 顺序后,明确选择仍没有歧义,附件 ID 或原始日志前缀无法标识这个集合。 +事件载荷为 `{ targets: [{ seq, imageIndexes }] }`。每个目标指向当前的 `user/message` 或 `tool/result` 节点。索引从零开始且严格递增,按内容深度优先顺序枚举所有图片,包括 tool-role 结果内容和先前省略的图片。相同附件 ID 的多次出现分别计数。位置替换改变 surface 顺序后,明确选择仍没有歧义,附件 ID 或原始日志前缀无法标识这个集合。 事件不带 `surfaceOp`,不创建消息,也不替换消息节点。插件的纯投影在 Session 提交事件前校验全部目标,拒绝缺失或已被遮蔽的节点、输出图片、重复目标、无效索引和已被省略的位置。重建过程派生不可变消息副本,将记录的位置标为 `ImageBlock.offloaded: true`。原始事件、消息 ID、来源和未受影响的内容块保持不变。恢复、分叉和回放从日志应用相同的选择。 diff --git a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml index 1bcfbf5d4a..94b8f7c295 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-client-session-references.md -2026-09-15-client-session-references.md: 2d727809b237ca919296dac82a3b201ba2dd8fbf -2026-09-15-client-session-references.zh.md: 34fa6526a57f43fd7636c68c7ed72bb982a129f2 +2026-09-15-client-session-references.md: 00f87cfb6f358218060a72199888690c3e46a091 +2026-09-15-client-session-references.zh.md: 7947a8a405d295eb6324ac33f06c0f2bc062c91b diff --git a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md index 2d727809b2..00f87cfb6f 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md +++ b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md @@ -101,7 +101,7 @@ Source counts remain authoritative in `SessionListState.byId[id].retainedBy`; UI Pending domains retain `SessionPendingInteractionMap`, request identities, precedence, publication disposers, and teardown delegation. The unified status includes the same effective request object; it does not copy requests or create a second pending registry. Workspace status indicators and Conversation composer selection read `useSessionStatus` instead of separate `useSessionPendingInteraction` and `useCompletedSessionIds` hooks. -Completion tracking subscribes to the existing `api-session/status` events so a running-to-idle transition is not lost in batched catalog snapshots. Catalog snapshots establish initial and reconnect baselines. A pending empty catalog is not evidence that Sessions disappeared. The update rules are: +Completion tracking subscribes to the existing `api-session/status` events so a running-to-idle transition is not lost in batched catalog snapshots. Host-list rows (`ids`) establish initial and reconnect running baselines; synthetic catalog and retained rows preserve independently observed status. A pending empty catalog is not evidence that Sessions disappeared. The update rules are: - An initial idle baseline does not create a completion reminder. - Observing running clears an earlier reminder and records the running baseline. diff --git a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md index 34fa6526a5..7947a8a405 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md @@ -101,7 +101,7 @@ Controller 将来源计数与每个活跃代的引用共同管理。每个来源 待处理领域保留 `SessionPendingInteractionMap`、请求身份、优先级、发布清理函数与卸载委托。统一状态包含同一个有效请求对象,不复制请求,也不创建第二套待处理注册表。Workspace 状态指示器与 Conversation composer 选择读取 `useSessionStatus`,不再分别读取 `useSessionPendingInteraction` 和 `useCompletedSessionIds` 钩子。 -完成跟踪订阅已有 `api-session/status` 事件,避免 running 到 idle 的变化在合批目录快照中丢失。目录快照建立初始与重连基线。pending 状态下的空目录不能证明 Session 已消失。更新规则如下: +完成跟踪订阅已有 `api-session/status` 事件,避免 running 到 idle 的变化在合批目录快照中丢失。Host 列表行(`ids`)建立初始与重连的 running 基线;目录合成行与 retained 行保留独立观察到的状态。pending 状态下的空目录不能证明 Session 已消失。更新规则如下: - 初始 idle 基线不产生完成提醒。 - 观察到 running 时清除旧提醒,并记录运行基线。 diff --git a/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml new file mode 100644 index 0000000000..d44576c5b1 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.md +2026-09-15-first-class-tool-role-messages.md: 3749ad698890073634b1753d3370f9c9dc9a2e18 +2026-09-15-first-class-tool-role-messages.zh.md: c97d84a7b3ceaee17ebb6fe828bd739dba5fb0ea diff --git a/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.md b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.md new file mode 100644 index 0000000000..3749ad6988 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.md @@ -0,0 +1,28 @@ +# Agent Note: First-class tool-role messages + +Status: implemented + +English | [中文](2026-09-15-first-class-tool-role-messages.zh.md) + +## Problem + +The released Session format stores tool results inside a user-role `tool-result` content block, while the model conversation and provider protocols treat a tool result as a separate role. Keeping both descriptions active makes validation, replay, and adapter projections disagree. + +## Decision + +Session format V4 stores one tool result as a first-class `role: 'tool'` message. Its `toolCallId`, tool source call id, result content, and optional error flag are validated together. The V3-to-V4 edge lifts exactly one released wrapper and refuses nested wrappers before publication, retaining the source generation. Current V4 decoding is native-only; wrapper rows are accepted only by the adjacent migration edge. + +Historical message and result extension fields keep distinct `plugin:message:` and `plugin:result:` names when their wrapper is removed. Complete original field names remain in each suffix, preventing collisions without adding core metadata fields. Opaque retention avoids inventing a shared field owner when the wrapper disappears. It retains duplicate values from distinct owners, and plugin consumers must use the V4 names. The wrapper alone supplies the interpreted call id and error flag; an old outer field with the same spelling remains opaque. The [conversion specification](../../../../packages/session/session-format-v3-to-v4/README.md#tool-results) owns exact preservation and refusal rules. + +The conversation role map is closed. A model-visible role must have a persisted Session event and an adapter projection, so adapters do not silently turn an unlogged extension role into user text. Provider-specific source kinds remain merge-extensible and are owned by their producers. + +## Alternatives considered + +- **Keep wrapper-shaped V4 rows** — this preserves the released payload but leaves the canonical role and provider wire formats inconsistent. +- **Accept both wrapper and native V4 rows** — dual current representations make encoding, decoding, recovery, and replay depend on which path produced the artifact. +- **Flatten historical nested results** — leaf text does not retain nested call IDs or error status, and providers did not interpret nested content uniformly. Unsupported migration preserves the original data until a lossless conversion is available. +- **Keep role extensions open** — an extension could reach a model request without a Session event and could not be reconstructed on replay. + +## Consequences + +The adjacent migration changes the logical message role without changing message identity, tool-call identity, or result content. Native V4 semantic failures are hard admission failures; recoverable decoding still applies to released V3 canonical tails. Adapters map the first-class role to their provider-specific tool-result representation. The duplicated message `toolCallId` and source `callId` remain as an explicit equality-checked provider field and source-identity field pair. diff --git a/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.zh.md b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.zh.md new file mode 100644 index 0000000000..c97d84a7b3 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.zh.md @@ -0,0 +1,28 @@ +# Agent Note:一等 tool-role 消息 + +Status: implemented + +[English](2026-09-15-first-class-tool-role-messages.md) | 中文 + +## 问题 + +已发布的 Session 格式把工具结果存储在 user-role 的 `tool-result` 内容块中,而模型对话与提供方协议把工具结果视为独立角色。两种描述同时存在会使校验、回放和适配器投影互相不一致。 + +## 决策 + +Session format V4 将一次工具结果存储为一等 `role: 'tool'` 消息。它的 `toolCallId`、工具来源调用标识、结果内容和可选错误标记一起校验。V3 到 V4 的边缘迁移只提升一个已发布的包装,并在发布前拒绝嵌套包装,保留源代际。当前 V4 解码仅接受原生形式;包装行只由相邻迁移边缘接受。 + +移除历史 wrapper 时,消息与结果的扩展字段分别保留为 `plugin:message:` 和 `plugin:result:` 名称。后缀保留完整原字段名,避免冲突且不添加核心 metadata 字段。不透明保留避免在 wrapper 消失时虚构共同字段 owner。不同 owner 的重复值仍分别保留,插件消费者必须使用 V4 名称。只有 wrapper 提供具有解释语义的调用 id 和错误标志;同名的旧外层字段保持不透明。[转换规范](../../../../packages/session/session-format-v3-to-v4/README.zh.md#tool-results)拥有精确的保留与拒绝规则。 + +对话角色 map 是封闭的。模型可见角色必须有持久 Session 事件和适配器投影,因此适配器不会把未记录的扩展角色静默转换为 user 文本。提供方特有的来源 kind 仍然可合并扩展,并由各生产方拥有。 + +## 曾考虑的替代方案 + +- **保留包装形式的 V4 行**——保留已发布载荷,但规范角色与提供方 wire 格式仍不一致。 +- **同时接受包装和原生 V4 行**——两种当前表示会让编码、解码、恢复和回放依赖于产出 artifact 的路径。 +- **展平历史嵌套结果**——叶子文本无法保留嵌套调用 ID 或错误状态,而且提供方对嵌套内容的解释并不一致。拒绝不支持的迁移会保留原始数据,等待能够保留全部信息的转换。 +- **保持角色扩展开放**——扩展角色可能在没有 Session 事件的情况下到达模型请求,也无法在回放时重建。 + +## 后果 + +相邻迁移会改变逻辑消息角色,但不改变消息身份、工具调用身份或结果内容。原生 V4 语义失败属于硬准入失败;可恢复解码仍适用于已发布 V3 的规范尾部。适配器把一等角色映射为各提供方自己的工具结果表示。消息 `toolCallId` 与来源 `callId` 的重复仍作为一对显式且经过相等性校验的提供方字段与来源字段保留。 diff --git a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml new file mode 100644 index 0000000000..db3f3c7cb5 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md +2026-09-17-developer-session-changes.md: 0545dfa4344f8ed87fe6343e13901647a5ccdac4 +2026-09-17-developer-session-changes.zh.md: 81c53115aaf4447dac358febcbd1310bb2a36cb2 diff --git a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md new file mode 100644 index 0000000000..0545dfa434 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md @@ -0,0 +1,35 @@ +# Agent Note: Developer messages for incremental session changes + +Status: implemented + +English | [中文](2026-09-17-developer-session-changes.zh.md) + +## Problem + +Dynamic tool changes need durable, ordered records before providers can preserve the cached conversation prefix while changing available tools. Encoding these changes as free-form reminders would lose their structured tool identity and couple session state to prompt wording. + +## Decision + +`DeveloperMessage` records admitted model-visible session changes in conversation order. Additions store only `toolName`; the containing event's `headerSeq` selects an earlier full `request/header` with exactly one schema for each added name. One event binds all its additions to one header revision. Additions replace the active same-name definition; removals identify the name without duplicating its schema. The header reference is absent when the message contains no additions. Same-name replacement, restart, fork, and surface replacement retain historical definition identity without consulting the current registry or latest request header. Intermediate registry changes that no admitted request exposes do not require developer records. + +`developer/message` carries the message and its admitting turn/step coordinates. Native readers and Session admission reject missing, forward, unknown, non-header, and ambiguous schema references, incomplete referenced definitions, and reject retired inline definitions while preserving unrelated JSON fields. `sourceEventSeqs` remains independent derivation metadata. A replacement retains its selected header and cites the shadowed surface nodes; combining additions from different header revisions requires separate events. Forks retain the referenced prefix, and compaction does not delete header events. Future cardinality-changing migrations must remap `headerSeq` as a same-artifact event reference. Empty developer content retains its surface position without adding a model message or shadowing the protected system head. The tools package owns the `tool-registry` source kind under the [producer-owned source rules](2026-09-09-producer-owned-message-sources.md). + +`ToolAdditionBlock.tool` is declared as optional `never` with `@persistenceReserved`. The schema history therefore records the rejected field: permitting any value later changes an existing value type and requires a format bump, while unrelated optional metadata remains additive. + +`ToolSchema.deferLoading` requests deferred definition loading independently of tool-addition history. Tool construction, registry projection, and prompt assembly preserve the marker. Dynamic addition and definition loading are separate facts; a predeclared deferred definition need not acquire a fabricated addition record. + +The V4 codec confines developer roles to the `developer/message` slot, including rejection from inbox and title-request arrays. Native validation checks required developer fields, historical header bindings, and developer-only tool-change blocks while preserving additional JSON properties. Optional metadata additions therefore remain readable under the persistence checker's optional-property rule; additional fields cannot weaken required-field, role, or open-step checks. An ignorable marker does not establish reader support: physical decoding preserves developer payloads until vocabulary-aware admission, while writers and native readers reject malformed known data. Developer admission leaves malformed ordinary message slots to decoder recovery. Installed Session adoption validates surface relationships without converting developer records into released-V3 user records. The [released migration rules](2026-08-31-released-session-format-migrations.md) continue to protect committed predecessor generations. + +The producer requirement has one scoped exception: finalized Session V4 reserves the persisted representation needed by issue #4146. Waiting for provider and UI implementations would couple the format release to those independent integrations. The reservation permits storage and validation only; no shipped profile emits developer records, and unsupported consumers throw. Production emission requires provider, UI, and compaction support together. + +## Alternatives considered + +**Use text reminders as developer content.** The format represents structured session changes; model instructions belong in system messages. Future developer content is unspecified rather than constrained to reminders. + +**Duplicate definitions in each addition.** Full request headers already preserve the exact schemas. A historical reference avoids a second persisted copy while retaining same-name replacement identity. Binding by the latest header or registry instead would reinterpret older additions. + +**Treat deferred loading as proof of a tool-addition record.** That would prevent predeclared deferred tools. The schema flag describes loading, while the block records a dynamic addition. + +## Consequences + +Session V4 persists the tool-change representation for issue #4146. Automatic emission, provider serialization, deferred loading, and UI presentation are intentionally deferred so this type-and-persistence change does not block the V4 merge. Both DeepSeek protocols and pi-ai throw for developer history and deferred-loading requests; Chat and Trajectory throw for developer events. Shipped model-output and SDK snapshot scenarios contain no developer records. diff --git a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md new file mode 100644 index 0000000000..81c53115aa --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md @@ -0,0 +1,35 @@ +# Agent Note:使用 developer 消息记录增量 Session 变更 + +Status: implemented + +[English](2026-09-17-developer-session-changes.md) | 中文 + +## Problem + +动态工具变更需要持久且有序的记录,提供方才能在改变可用工具时保留对话的缓存前缀。将这些变更编码为自由文本提醒会丢失结构化的工具身份,并将 Session 状态与提示词措辞耦合。 + +## Decision + +`DeveloperMessage` 按对话顺序记录已接纳且模型可见的 Session 变更。添加块仅存储 `toolName`;所在事件的 `headerSeq` 选择更早的完整 `request/header`,其中每个添加名称必须恰好对应一个模式。同一事件的所有添加绑定到同一个请求头版本。添加替换当前同名定义;移除仅记录名称,不重复模式。没有添加块的消息不携带请求头引用。同名替换、重启、fork 和 surface 替换保留历史定义身份,不查询当前注册表或最新请求头。没有被任何已接纳请求暴露的中间注册表变更无需 developer 记录。 + +`developer/message` 携带消息及其接纳 turn/step 坐标。原生读取方和 Session 接纳逻辑拒绝缺失、前向、未知、非请求头及歧义模式引用、不完整的被引用定义,并拒绝已退役的内嵌定义,同时保留无关 JSON 字段。`sourceEventSeqs` 保持为独立的派生元数据。替换保留选定的请求头,并引用被覆盖的 surface 节点;不同请求头版本的添加必须分属不同事件。fork 保留所引用的前缀,压缩不删除请求头事件。未来改变事件数量的迁移必须将 `headerSeq` 作为同一文件内的事件引用重映射。空 developer 内容保留其 surface 位置,不添加模型消息,也不能覆盖受保护的 system 头节点。tools 包按照[生产者自有来源规则](2026-09-09-producer-owned-message-sources.zh.md)拥有 `tool-registry` 来源种类。 + +`ToolAdditionBlock.tool` 声明为可选的 `never`,并标注 `@persistenceReserved`。模式历史因此记录这个被拒绝的字段:后续允许任何值都会改变现有值类型并要求格式递增,无关的可选元数据仍属于可兼容添加。 + +`ToolSchema.deferLoading` 请求延迟加载工具定义,与工具添加历史相互独立。工具构造、注册表投影与提示词组装保留该标记。动态添加与定义加载是不同事实;预先声明的延迟加载定义无需虚构添加记录。 + +V4 编解码器将 developer 角色限定在 `developer/message` 字段内,并拒绝 inbox 与标题请求数组中的该角色。原生验证检查 developer 必需字段、历史请求头绑定及工具变更块仅限 developer 的约束,同时保留附加 JSON 属性。因此,可选元数据添加符合持久化检查器的可选属性规则,仍可读取;附加字段不能削弱必需字段、角色或打开 step 的检查。可忽略标记不代表读取方支持该事件:物理解码保留 developer 载荷,直到按词表执行接纳;写入方和原生读取方仍拒绝格式错误的已知数据。developer 接纳逻辑将格式错误的普通消息字段留给解码器恢复。已安装的 Session 接纳逻辑验证 surface 关系,不把 developer 记录转换为已发布 V3 的 user 记录。[已发布格式迁移规则](2026-08-31-released-session-format-migrations.zh.md)继续保护已提交的前代文件。 + +产生方要求有一个限定例外:已定稿 Session V4 为 issue #4146 保留所需的持久化表示。等待提供方与 UI 实现会将格式发布与这些独立集成耦合。该预留仅允许存储和验证;已提供的 profile 不发出 developer 记录,不支持的消费者会抛出错误。生产环境发出这些记录要求提供方、UI 与压缩支持一起落地。 + +## Alternatives considered + +**将文本提醒作为 developer 内容。** 此格式表示结构化 Session 变更;模型指令属于 system 消息。未来的 developer 内容尚未指定,不将其限制为提醒。 + +**在每次添加中重复定义。** 完整请求头已经保留精确模式。历史引用避免第二份持久化副本,同时保留同名替换的身份。若绑定到最新请求头或注册表,则会重新解释较早的添加。 + +**将延迟加载视为存在工具添加记录的证据。** 这会阻止预先声明的延迟工具。模式标记描述加载方式,内容块记录动态添加。 + +## Consequences + +Session V4 为 issue #4146 持久化工具变更表示。自动发出事件、提供方序列化、延迟加载与 UI 展示有意留待后续实现,使此类型与持久化变更不阻塞 V4 合并。DeepSeek 两种协议与 pi-ai 对 developer 历史及延迟加载请求抛出错误;Chat 与 Trajectory 对 developer 事件抛出错误。已提供的模型输出与 SDK 快照场景不包含 developer 记录。 diff --git a/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml new file mode 100644 index 0000000000..c3afeacd89 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.md +2026-09-17-native-v4-read-validation.md: b111e9f1dd4aae6557b7893a9f334445ef0c85bc +2026-09-17-native-v4-read-validation.zh.md: 20f1dc53b6eda42834e169c18f7b269e2933d27c diff --git a/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.md b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.md new file mode 100644 index 0000000000..b111e9f1dd --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.md @@ -0,0 +1,33 @@ +# Agent Note: Mandatory native V4 relationship validation + +Status: implemented + +English | [中文](2026-09-17-native-v4-read-validation.zh.md) + +## Problem + +Tool-role results cannot be checked through the released V3 user-role representation without projecting away current fields. Replacing that validation view requires a native reader to retain the earlier lifecycle, retired-syntax, and system-message checks. The representation change and its mandatory admission therefore belong together. + +An event can satisfy its TypeScript declaration and message rules while contradicting earlier durable events. A tool result without an advertised call and a checkpoint naming another compaction both contain locally valid fields. Accepting either as a current Session makes later readers depend on damaged relationships, and tightening admission after release can strand already-written histories. + +## Decision + +The V4 format restorer and current JSONL scanner share one mandatory cross-event relationship pass before exposing a restored artifact or storage handle. It checks turn and step order, advertised tool calls and settlements, PTC parentage and settlement identity, retry chains and request providers, human-message title citations, command completion references, compaction ownership and current spans, and the protected system head. The installed event set controls semantic interpretation, including compaction prepasses and title references. Unknown ignorable records retain their payloads and original positions; known records remain validated even when marked ignorable. The check reads native event fields without altering artifacts or projecting them into a historical format. JSON argument comparisons inspect own properties in both Node and the worker; inherited prototype members cannot satisfy recorded fields. The [tool-role decision](2026-09-15-first-class-tool-role-messages.md) owns result representation. + +An unfinished tail may retain an open turn, step, tool call, or compaction. A closing event must settle the relationships it closes. An inherited unfinished compaction ends at its `session/end-seed` marker; it does not constrain the child's lifecycle. Repair message identities retain their historical numeric suffix after earlier migrations change sequence coordinates. Fork repairs retain their separately validated native identities. + +Installed Session adoption continues to own event envelopes, message roles and metadata, canonical request headers, and surface replacement reference coverage. Optional runtime invariants provide diagnostics; their installation is not required for durable admission. Native system-message admission also validates coordinates, identity, content blocks, and known image/tool-call fields before physical recovery can discard rows. Additional JSON fields and unknown nonempty content tags remain intact; retired tool-result wrappers are refused. Retired `request/header.header.system` and required `tool/code-dispatch*` tags remain hard refusals before recovery; obsolete ignorable PTC records remain opaque. Physical framing alone does not establish semantic validity. + +A retired tool-result wrapper outside its owning `tool/result` row would require changing the event, role, or source to represent it in V4. The adjacent migration lifts only the canonical owned wrapper; target restoration refuses wrappers remaining in interpreted content. Native row admission applies the same refusal before recoverable tail suppression. The check follows declared message, content, and Assistant-stream slots instead of recursively inspecting JSON, so tool arguments, replay state, schema parameters, nested extensions, and unknown ignorable payloads retain their recorded values. + +`EpochHeader.system` explicitly reserves the retired key as `system?: never` with `@persistenceReserved`. The catalog retains its empty value set so permitting a value is a change to a forbidden field, rather than an ordinary optional-field addition. The native reader and Session adoption continue to reject that key; system prompts remain `system/message` events. + +## Alternatives considered + +**Project V4 back into a frozen V3 validation view.** This couples current acceptance to retired representations and invites new fields to disappear in the projection. Frozen generations remain independently readable, while the current restorer interprets its own fields. + +**Rely on optional runtime invariants.** Detached readers and restoration paths may not install diagnostic companions. A required relationship must be checked before publication or consumption of the restored Session. + +## Consequences + +The native restorer maintains one bounded state machine per read and rejects contradictions before successor publication. Frozen V0–V3 validators and committed Session generations remain unchanged. Public catalog regressions cover invalid relationships alongside partial tails, inherited cuts, immutable unknown attribution, and complete tool exchanges; these checks enforce the declared V4 representation without changing its schemas. Breaking changes require a successor; compatible additions use new acknowledgements, and implementation fixes preserve the declared meaning. diff --git a/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.zh.md b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.zh.md new file mode 100644 index 0000000000..20f1dc53b6 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.zh.md @@ -0,0 +1,33 @@ +# Agent Note: 原生 V4 关系的强制校验 + +Status: implemented + +[English](2026-09-17-native-v4-read-validation.md) | 中文 + +## Problem + +tool 角色结果不能通过已发布的 V3 user 角色表示进行校验,否则投影会丢弃当前字段。替代该校验视图后,原生读取方必须保留原有的生命周期、退役语法和 system 消息检查。因此,表示变更与必需的接纳校验需要一同完成。 + +事件即使符合 TypeScript 声明和消息规则,也可能与较早的持久化事件矛盾。没有声明调用的工具结果、指向另一压缩事务的检查点,都可以拥有局部有效字段。将它们接纳为当前 Session 会让后续读取器依赖损坏的关系;发布后再收紧准入则可能让已写入的历史无法读取。 + +## Decision + +V4 格式恢复器与当前 JSONL 扫描器共用同一强制跨事件关系校验,在公开恢复产物或存储句柄之前执行。它检查 turn 与 step 顺序、声明的工具调用及其结算、PTC 父子关系与结算身份、重试链与请求 provider、标题的人类消息引用、命令完成引用、压缩归属与当前区间,以及受保护的 system 首节点。已安装事件集合控制语义解释,包括压缩预扫描和标题引用。未知的可忽略记录保留其载荷与原始位置;已知记录即使标记为可忽略仍会接受校验。校验直接读取原生事件字段,不修改产物,也不将其投影为历史格式。Node 和 Worker 中的 JSON 参数比较都检查自有属性,继承的原型成员不能代替记录字段。[工具角色决策](2026-09-15-first-class-tool-role-messages.zh.md)负责结果表示。 + +未完成的尾部可以保留打开的 turn、step、工具调用或压缩事务。关闭事件必须结清它关闭的关系。继承的未完成压缩事务在其 `session/end-seed` 标记处结束,不约束子 Session 的生命周期。较早迁移改变序号坐标后,修复消息身份仍保留历史数字后缀。fork 修复保留经过独立校验的原生身份。 + +已安装的 Session 接纳器继续负责事件封装、消息角色与元数据、规范请求头,以及 surface 替换的引用覆盖。可选运行时不变式提供诊断;持久化准入不要求安装它们。原生 system 消息准入还会在物理恢复可能丢弃行之前,校验坐标、身份、内容块及已知 image/tool-call 字段。额外 JSON 字段和非空的未知内容标签保持不变,退役的 tool-result 包装会被拒绝。退役的 `request/header.header.system` 和必需的 `tool/code-dispatch*` 标签仍在恢复前强制拒绝;标记为可忽略的过时 PTC 记录保持不透明。仅通过物理分帧不能证明语义有效。 + +退役的 tool-result 包装若不属于对应的 `tool/result` 行,就需要改变事件、角色或来源才能在 V4 中表示。相邻迁移只提升规范的自有包装;目标恢复器拒绝解释内容中剩余的包装。原生行准入在可恢复尾部被忽略之前执行同样的拒绝。检查沿声明的消息、内容和 Assistant stream 字段进行,不递归扫描 JSON,因此工具参数、replay state、schema 参数、嵌套扩展和未知可忽略载荷保留其记录值。 + +`EpochHeader.system` 通过带有 `@persistenceReserved` 的 `system?: never` 显式保留退役键。目录保留其空值集合,使允许某个值被识别为对禁止字段的修改,而非普通可选字段添加。原生读取方和 Session 接纳继续拒绝该键;系统提示词仍由 `system/message` 事件承载。 + +## Alternatives considered + +**将 V4 投影回冻结的 V3 校验视图。** 这会将当前准入与退役表示绑定,并容易让新增字段在投影中消失。冻结代际仍可独立读取,当前恢复器解释自己的字段。 + +**依赖可选运行时不变式。** 分离读取器和恢复路径可能不安装诊断组件。必需关系必须在发布或消费恢复后的 Session 之前完成校验。 + +## Consequences + +原生恢复器为每次读取维护独立状态机,在发布后继文件之前拒绝矛盾。冻结的 V0–V3 校验器及已提交的 Session 代际保持不变。公开目录回归覆盖无效关系、部分尾部、继承切分点、未知归属的不可变保存,以及完整工具交互;这些检查落实已声明的 V4 表示,不改变其 schema。破坏性变更要求后继版本;兼容新增使用新的确认记录,实现修复须保留声明的含义。 diff --git a/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml new file mode 100644 index 0000000000..e2b272908e --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.md +2026-09-17-persistence-attribution-policy.md: 19bebc8bc186f4b2b7e2e561fb6a53ceadcebabf +2026-09-17-persistence-attribution-policy.zh.md: 3561c1d1afca5402cb94b1578603c4f1a2fc89a4 diff --git a/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.md b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.md new file mode 100644 index 0000000000..19bebc8bc1 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.md @@ -0,0 +1,35 @@ +# Agent Note: Recorded user-source attribution compatibility + +Status: implemented + +English | [中文](2026-09-17-persistence-attribution-policy.zh.md) + +## Problem + +A producer-owned message source appears transitively in several persisted event types. A new attribution kind changes their union fingerprints even when existing readers preserve its fields without the producer. Request-only prompts need no durable identity, but constructing them as Session messages adds unnecessary source alternatives to that union. + +## Decision + +The core-owned user-message source property binds the [recorded compatibility policy](../process/2026-09-17-persistence-schema-review.md). A producer separately qualifies its literal wire kind as attribution-only. Both saved schemas must carry compatible policy state before a qualified addition receives a same-version classification. Existing alternatives remain structurally compared; missing policy, unqualified additions, removals, and changes to existing semantic groups retain strict classification. Fixed system, model, and tool source fields do not participate. + +The tmux-context producer qualifies its location attribution. Its own projection uses the kind to avoid repeated injection, while readers without that producer retain the recorded content and every source JSON property. The qualification promises reader independence; it does not forbid producer-local duplicate suppression. + +`RequestMessage` accepts a durable `Message` or a user-only `RequestUserInput` with content and no `id` or `source`. The LLM service and provider serializers accept both; Session writes, Agent delivery, and persisted title-request inputs require durable messages. Auto Review's outer prompt and the compaction summarizer's final instruction use request-only inputs and retain their content and freezing. The caller receives no implicit durable conversion. Assistant replay metadata and tool-result correlation retain their existing requirements. + +The finalized V4 acknowledgement records the user-source policy and removes the two request-only source registrations. Its original predecessors and header transition remain intact. This does not grant a general exception for removing accepted variants: the [producer-source migration](2026-09-09-producer-owned-message-sources.md) preserves its producer mappings and extension namespaces, including historical request-only kinds, independently of active source declarations. Catalog generation and comparison remain owned by the [persistence reference](../../../../docs/persistence-changes/README.md#compatibility-rules). + +## Alternatives considered + +**Treat every source addition as breaking.** This would require a Session-format increment for attribution that readers already retain safely, without distinguishing it from semantic changes. + +**Relax every discriminated union or infer compatibility from current names.** A generic exception would admit semantic variants. Current declarations cannot establish what an older snapshot promised, and structural equality does not establish ownership of a source property. + +**Use durable messages for every request.** Detached prompts would retain manufactured identities and unnecessary source declarations. The explicit user-only alternative permits their removal while typed Session interfaces retain durable identity requirements. + +**Narrow historical context forms to current writer examples.** Writer examples do not establish every value admitted by released readers. Those read-facing variants remain represented. + +## Consequences + +A qualified addition still changes affected event fingerprints and requires an acknowledgement. Reviewers must verify the producer's attribution promise; type analysis cannot establish replay semantics or detect behavior hidden in opaque values. + +Codec-to-Session tests retain unknown user attribution and extra JSON fields without the producer. Provider equality tests compare request-only and durable inputs, while type assertions reject request-only inputs at durable writes. Recorded Session generations and the V3-to-V4 conversion remain independent of catalog policy and rendering. diff --git a/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.zh.md b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.zh.md new file mode 100644 index 0000000000..3561c1d1af --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.zh.md @@ -0,0 +1,35 @@ +# Agent Note:已记录的 user-source 归属兼容性 + +Status: implemented + +[English](2026-09-17-persistence-attribution-policy.md) | 中文 + +## 问题 + +生产者拥有的消息 source 会传递性地出现在多个持久化事件类型中。即使已有读取方无需该生产者也能保留字段,新增归属 kind 仍会改变这些联合类型的指纹。仅供请求使用的提示不需要持久身份,但将其构造成 Session 消息会为联合类型增加不必要的 source 分支。 + +## 决策 + +核心拥有的 user-message source 属性绑定[已记录的兼容性策略](../process/2026-09-17-persistence-schema-review.zh.md)。生产者另行将其 wire 字面量 kind 声明为仅用于归属。双方保存的 schema 必须具有兼容的策略状态,符合条件的添加才能获得同版本分类。已有分支继续接受结构比较;缺失策略、未标记的添加、删除以及已有语义分组的变更继续采用严格分类。固定的 system、model 和 tool source 字段不参与。 + +tmux-context 生产者将位置归属标记为符合条件。其自身投影使用 kind 避免重复注入,而未安装该生产者的读取方保留已记录内容及 source 的每个 JSON 属性。该标记承诺读取方不依赖生产者,并不禁止生产者内部的去重。 + +`RequestMessage` 接受持久化 `Message`,或仅含 content、没有 `id` 和 `source` 的 user 专用 `RequestUserInput`。LLM 服务和 provider 序列化器接受两者;Session 写入、Agent 交付及持久化标题请求输入要求持久化消息。Auto Review 的外层提示和压缩摘要器的最终指令使用仅供请求使用的输入,并保留内容与冻结行为。调用方不会获得隐式持久化转换。Assistant 回放元数据和工具结果关联保持原有要求。 + +已定稿的 V4 确认记录保存 user-source 策略,并移除两个仅供请求使用的 source 注册。原有前驱和 header 迁移保持不变。这不构成删除已接受分支的通用例外:[producer-source 迁移](2026-09-09-producer-owned-message-sources.zh.md)独立于活动 source 声明保留生产者映射与扩展命名空间,包括历史的仅供请求使用的 kind。目录生成和比较仍由[持久化参考](../../../../docs/persistence-changes/README.zh.md#compatibility-rules)负责。 + +## 考虑过的替代方案 + +**将所有 source 添加视为破坏性变更。** 这会要求为读取方已能安全保留的归属信息提升 Session 格式版本,无法区分它与语义变更。 + +**放宽所有可辨识联合或从当前名称推断兼容性。** 通用例外会接纳语义分支。当前声明不能确定旧快照作出的承诺,结构相等也不能确定 source 属性的归属。 + +**为每个请求使用持久化消息。** 独立提示会保留人为制造的身份和不必要的 source 声明。显式的 user 专用分支允许移除它们,同时让带类型的 Session 接口继续要求持久身份。 + +**将历史 context 形式收窄到当前写入方示例。** 写入方示例不能确定已发布读取方接纳的全部值。这些面向读取的分支继续保留。 + +## 影响 + +符合条件的添加仍会改变相关事件指纹,并要求确认记录。Review 者必须验证生产者的归属承诺;类型分析不能确定回放语义,也不能发现不透明值中隐藏的行为。 + +Codec 到 Session 的测试在未安装生产者时保留未知 user 归属和额外 JSON 字段。Provider 等价测试比较仅供请求使用的输入与持久化输入,类型断言则拒绝在持久化写入处使用仅供请求使用的输入。已记录的 Session 世代及 V3→V4 转换不依赖目录策略和渲染。 diff --git a/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml new file mode 100644 index 0000000000..a66f2afe77 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.md +2026-09-19-lossless-projection-checkpoint-json.md: 9c7d15dbd2d570eaa544f168d2c2ef882558d5ca +2026-09-19-lossless-projection-checkpoint-json.zh.md: 8c2b720358351af33a6d07888002c65d0cc30363 diff --git a/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.md b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.md new file mode 100644 index 0000000000..9c7d15dbd2 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.md @@ -0,0 +1,24 @@ +# Agent Note: Lossless projection checkpoint JSON + +Status: implemented + +English | [中文](2026-09-19-lossless-projection-checkpoint-json.zh.md) + +## Problem + +Projection checkpoints can contain opaque extension data and message metadata. A JSON key named `__proto__` is ordinary recorded data. The Zod JSON parser drops that own key while rebuilding objects, so reopening a valid checkpoint can yield different projection state from replaying the Session log. + +## Decision + +The checkpoint value schema uses the existing `isJsonValue` predicate from `dsh-util-values`. It enforces the same lossless JSON rules as the checkpoint writer's `snapshotJsonValue` without rebuilding valid objects. Validation still rejects non-JSON and lossy values. Storage-domain table values are immutable borrowed records; the validator does not supply a defensive-copy guarantee. + +## Alternatives considered + +- **Keep `z.json()`.** Its object reconstruction removes valid own keys, so a successful validation can still change the checkpoint value. +- **Validate and clone with `snapshotJsonValue`.** This preserves keys but copies already immutable stored values. The read-only predicate matches the storage-domain borrowed-value contract. + +## Consequences + +Domain reads preserve every valid own key in checkpoint values, including nested `__proto__` and `constructor` properties. A projection's `stateSchema` still owns its hydration value; opaque fields must use validation that preserves their keys. The borrowed-value validator does not create an independent copy or project to JSON Schema. + +The domain version remains unchanged because the stored JSON representation is unchanged; this corrects its reader. Regression coverage opens a synthetic fixture produced by the real writer, then writes, closes, and reopens it through `StorageDomain`. Session format versions and historical generations do not change. [Predecessor recovery and Session-format binding](2026-09-02-projcache-cross-version-read-compat.md) continue to own cache-version and identity compatibility. diff --git a/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.zh.md b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.zh.md new file mode 100644 index 0000000000..8c2b720358 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.zh.md @@ -0,0 +1,24 @@ +# Agent Note: 无损投影检查点 JSON + +Status: implemented + +[English](2026-09-19-lossless-projection-checkpoint-json.md) | 中文 + +## 问题 + +投影检查点可以包含不透明扩展数据和消息元数据。名为 `__proto__` 的 JSON 键是普通记录数据。Zod JSON 解析器在重建对象时丢弃该自有键,因此重新打开有效检查点可能得到与回放 Session 日志不同的投影状态。 + +## 决策 + +检查点值 schema 使用 `dsh-util-values` 中既有的 `isJsonValue` 谓词。它执行与检查点写入器 `snapshotJsonValue` 相同的无损 JSON 规则,不重建有效对象。校验仍拒绝非 JSON 和有损值。Storage-domain 表值是不可变的借用记录;校验器不提供防御性复制保证。 + +## 备选方案 + +- **保留 `z.json()`。** 其对象重建会移除有效自有键,因此校验成功仍可能改变检查点值。 +- **用 `snapshotJsonValue` 校验并复制。** 这能保留键,但会复制已经不可变的存储值。只读谓词符合 storage-domain 的借用值约定。 + +## 影响 + +Domain 读取保留检查点值中的每个有效自有键,包括嵌套的 `__proto__` 和 `constructor` 属性。Projection 的 `stateSchema` 仍拥有其 hydration 值;不透明字段必须使用保留其键的校验器。借用值校验器不生成独立副本,也不投影为 JSON Schema。 + +存储 JSON 表示未变,因此 domain 版本不变;本修改修正其读取器。回归测试打开真实写入器生成的合成 fixture,再通过 `StorageDomain` 写入、关闭并重新打开。Session 格式版本与历史代际不变。[前代恢复与 Session 格式绑定](2026-09-02-projcache-cross-version-read-compat.zh.md) 继续负责缓存版本与身份兼容性。 diff --git a/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml new file mode 100644 index 0000000000..4ede5bd457 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.md +2026-09-19-v3-incomplete-child-catalog-evidence.md: 22ca91502425257ed30aa4962f5a38497b8a8a92 +2026-09-19-v3-incomplete-child-catalog-evidence.zh.md: c11e6de2c27b9892a72c28f327b6d06834d84038 diff --git a/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.md b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.md new file mode 100644 index 0000000000..22ca915024 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.md @@ -0,0 +1,29 @@ +# Agent Note: Preserve V3 Sessions with incomplete child catalog evidence + +Status: implemented + +English | [中文](2026-09-19-v3-incomplete-child-catalog-evidence.zh.md) + +## Problem + +A valid V3 child log can have no own descriptor, an unsupported descriptor version, or multiple descriptors. Its header still establishes its identity and parent relationship. Requiring one supported descriptor to migrate the parent makes unavailable discovery fields prevent access to otherwise readable history. + +## Decision + +The V3→V4 migration appends a missing parent catalog entry only when exactly one supported own child descriptor supplies its discovery fields. Other descriptor counts and unsupported versions contribute no new catalog fact. Existing parent entries and child events remain intact. This replaces only the missing-evidence refusal in the [adjacent migration decision](../architecture/2026-08-31-released-session-format-migrations.md). + +Known child creation times must still match existing parent entries. Mode/label and descriptor fields are checked only for exactly one supported own descriptor. Invalid fields in that descriptor, corrupt logs, unreadable membership, unsupported selected generations, and changed source revisions retain their existing failures. + +## Alternatives considered + +**Refuse the whole parent.** Discovery metadata is insufficient to justify making valid parent history unavailable. + +**Choose the first or last descriptor.** [`foldSubagentDescriptor()`](../../../../packages/subagent/subagent/src/descriptor.ts) takes the first under the establishing provider’s exactly-once rule; the [identity projection](../../../../packages/subagent/subagent/src/projection.ts) takes the last to override inherited identities. Multiple own records violate that rule. Backfill requires one own record rather than choosing between these consumer policies. + +**Infer missing fields.** Invented mode or label fields would become durable catalog facts without evidence. + +## Consequences + +A historical child without a usable descriptor remains readable by id but may be absent from its parent's direct-child catalog. Existing catalog entries remain visible. Once a V4 successor is published, opening it does not rescan historical children; automatic later catalog repair is outside this migration. Preparation still rechecks child revisions before publication, so newly available evidence cannot silently bypass source consistency checks. + +Unit, JSONL read/write, and Preview packing tests cover unavailable evidence, unchanged source bytes, retained entries, identity conflicts, and evidence changes before publication. diff --git a/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.zh.md b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.zh.md new file mode 100644 index 0000000000..c11e6de2c2 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.zh.md @@ -0,0 +1,29 @@ +# Agent Note: 保留子目录证据不完整的 V3 Session + +Status: implemented + +[English](2026-09-19-v3-incomplete-child-catalog-evidence.md) | 中文 + +## Problem + +有效 V3 子日志可能没有自身 descriptor、descriptor 版本不受支持,或存在多个 descriptor。其 header 仍能确定身份及父子关系。要求一个受支持的 descriptor 才迁移父日志,会让不可获得的发现字段阻止读取原本可读的历史。 + +## Decision + +V3→V4 迁移只在恰好一个受支持的自身子 descriptor 提供发现字段时,追加缺失的父目录项。其他 descriptor 数量及不受支持的版本不贡献新的目录事实。已有父目录项和子事件保持完整。这只替代[相邻迁移决策](../architecture/2026-08-31-released-session-format-migrations.zh.md)中的证据缺失拒绝规则。 + +已知子创建时间仍必须与已有父目录项一致。只有恰好一个受支持的自身 descriptor 时,才校验其字段并比较 mode/label。该 descriptor 字段无效、日志损坏、成员关系不可读、所选代际不受支持以及源修订变化仍保留原有失败行为。 + +## Alternatives considered + +**拒绝整个父 Session。** 发现元数据不足以成为禁止读取有效父历史的理由。 + +**选择首个或末个 descriptor。** [`foldSubagentDescriptor()`](../../../../packages/subagent/subagent/src/descriptor.ts) 依据建立提供方恰好写入一次的规则取首个;[身份投影](../../../../packages/subagent/subagent/src/projection.ts)取末个以覆盖继承身份。多个自身记录违反该规则。补填要求一个自身记录,而不在这两种消费者策略之间做选择。 + +**推断缺失字段。** 推断的 mode 或 label 会在没有证据的情况下成为持久目录事实。 + +## Consequences + +没有可用 descriptor 的历史子 Session 仍可按 id 读取,但可能不出现在其父级的直属子目录中。已有目录项仍可见。V4 后继发布后,打开它不会重新扫描历史子日志;后续自动修复目录不属于本迁移。准备过程仍会在发布前复查子修订,因此新出现的证据无法悄悄绕过源一致性检查。 + +单元、JSONL 读写和 Preview 打包测试覆盖不可用证据、源字节不变、条目保留、身份冲突以及发布前的证据变化。 diff --git a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml index e678639894..21f75ab4b4 100644 --- a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md -2026-07-27-web-subagent-conversations.md: aacb52eca5680534b74abd42ca07c2b568c23e21 -2026-07-27-web-subagent-conversations.zh.md: 30c41f03703004e3175cee8fad9d11e0cf93f06a +2026-07-27-web-subagent-conversations.md: 3798a5a2e5deb8b3801298def31c3a1890877796 +2026-07-27-web-subagent-conversations.zh.md: 4531528dd2a58baff3aaeaf53f20e037fce6cec4 diff --git a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md index aacb52eca5..3798a5a2e5 100644 --- a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md +++ b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md @@ -10,13 +10,13 @@ Session-backed subagents have durable identities, persisted transcripts, and a d The browser must preserve the [continuable subagent contract](../../implemented/feature/2026-07-28-continuable-subagent-conversations.md): a continuable child has at most one process-local Activation, accepts later work only through the exact live direct parent, and uses the Agent inbox as its sole FIFO. Viewing history must not create an Activation. Once an inbox message is accepted, the HTTP caller neither owns its execution nor gains a cancellation handle. -The UI must also preserve the membership, modes, and diagnostics of the [durable catalog](../../archived/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md). The shared service reports live-preferred corpus activity, while the Web projection replaces it with the exact child Agent driver's `running` or `inactive` state. Neither activity is a durable outcome or a promise that continuation will succeed. +The UI must also preserve the membership and modes of the [durable catalog](../architecture/2026-09-01-parent-owned-subagent-catalog.md). The Web projection adds the exact child Agent driver's `running` or `inactive` state. Neither activity is a durable outcome or a promise that continuation will succeed. ## Decision The Web product exposes the selected session's direct session-backed subagents from the current-title lineage region in the header. Users can lazily expand descendant catalogs and open either mode in the existing conversation region. A one-shot child is permanently read-only. A continuable child accepts human follow-ups only while its exact direct-parent Agent is live; otherwise its persisted transcript remains readable with a recovery explanation. -The same header row can open a child in the right Sidebar as `dsh-resource://chat/session/?parent=&mode=`. The open prefers a separate pane and falls back to the current pane when no split is available. The Sidebar tab renders the shared Conversation Component Factory with its width controls omitted, so main and embedded conversations share one assembly without sharing layout chrome. +The same header row can open a child in the right Sidebar as `dsh-resource://subagentchat/session/?parent=&mode=`. The open prefers a separate pane and falls back to the current pane when no split is available. The Sidebar tab renders the shared Conversation Component Factory with its width controls omitted, so main and embedded conversations share one assembly without sharing layout chrome. Every opened child carries a catalog-derived address `{ parentSessionId, childSessionId, mode }`. The mode-bearing address, not lineage or the coarse origin marker, selects dedicated history and prompt transports. History reads the persisted session without activation. A continuable prompt carries Queue or Steer delivery through `subagent.prompt` and succeeds at inbox acceptance with `{ messageId }`; it does not expose an Activation, wait for completion, or return an outcome. Adjacent-Agent model messages use the separately owned fixed-Steer operation. @@ -32,16 +32,16 @@ The Figma [subagent list](https://www.figma.com/design/jRBBK7zBgcszdVWQ0Fh5J8/Ha | Design intent | Shipped contract | | --- | --- | -| The session header opens a compact child list. | The trigger aggregates the complete subagent-only descendant lineage; the tree shows every direct catalog entry in service order, including disabled diagnostics. | +| The session header opens a compact child list. | The trigger counts healthy direct entries returned by the parent catalog service. | | Selecting a row reuses the conversation UI. | Addressed history never activates the child; only a continuable row with a live parent retains the ordinary composer. | -| Nested agents expand progressively. | Each row carries a one-level `hasChildren` snapshot; disclosure reserves known direct-descendant rows immediately, then loads only that row's direct catalog and retains its own parent address. | +| Nested agents expand progressively. | A row remains expandable until its own catalog has loaded empty; expansion loads only that direct catalog and retains the row's parent address. | | Rows show labels, state, usage, and active duration without duplicating sidebar rows. | Mode and `running`/`inactive` activity are textual as well as visual; optional title, durable token usage, and active-turn duration come from the list's retained projection values. Compact duration loses smaller units above one day, while hover and accessible naming retain exact whole seconds. `SessionHeader.origin` removes duplicate navigation rows but grants no capability. | ## Product contract -The descendant-count control is absent only when a complete empty direct-catalog response agrees with the session-summary projection that no subagent descendants are known. On an ordinary session, a slash separates the current title from that count control. Every subagent breadcrumb combines its compact 12px title with a fixed double chevron: the current breadcrumb uses primary color and weight 500, while ancestors use tertiary color and weight 400. Hovering a combined control for 150ms opens its direct-parent catalog, with a short crossing grace for the portaled menu; ArrowDown remains the keyboard entry path. Clicking an ancestor cancels pending hover, closes an open catalog, and only navigates upward. Each direct-parent catalog enables sibling switching and bolds its selected row; its label overrides the session-summary title, and every missing switcher catalog refreshes automatically. Only the current subagent appends its own descendant-count control. Long titles truncate before the fixed chevron. The count trigger counts every known session-summary descendant reached through an uninterrupted `origin: 'subagent'` lineage, stops at ordinary forks, and shows ongoing activity when any counted descendant is running. Because ordinary sidebar rows hide subagent-origin sessions, the Workspace browser indexes the same uninterrupted lineage onto each visible ordinary row: any running descendant supplies the shared tertiary-grey ongoing loader and exact count in hover and assistive text without describing an idle parent as running. An ordinary fork starts a separate aggregation subtree. Pending interaction outranks parent running; either remains primary while descendant activity becomes a second hover and assistive status. An ordinary Workspace row with a pending approval, plan review, or question replaces its relative time with the compact label `Approval`, `Plan review`, or `Answer`; hover and assistive details retain the full status and relative time. With neither primary state present, descendant activity outranks an unviewed completion reminder, which returns after the last running descendant stops. Every healthy direct-catalog row carries a read-time `hasChildren` hint derived only from direct lineage headers with durable `origin: 'subagent'`; normal healthy and diagnostic subagent candidates carry that marker, while ordinary forks do not. This lookahead reads no descendant event log, and the descriptor-backed catalog loaded after disclosure remains authoritative. When summaries establish descendants before that catalog exists or after a stale empty response, the action stays visible and exposes only disabled loading rows until opening it refreshes the catalog; summary-only rows never grant navigation. The UI omits disclosure for a known leaf before interaction; the hint does not promise that the child will remain a leaf. While an expanded direct catalog is loading, known lineage reserves one disabled loading row per direct descendant without recursively fetching descendant catalogs. The tree then presents continuable and one-shot rows, falling back to the session id when an optional one-shot label is absent. Corrupt, unsupported, and unavailable candidates remain visible as disabled diagnostic rows. +The child-count control appears when the direct catalog contains entries or its read fails; it stays hidden while an empty catalog is absent or loading, and after a successful empty read. On an ordinary session, a slash separates the current title from that control. Every subagent breadcrumb combines its compact 12px title with a fixed double chevron: the current breadcrumb uses primary color and weight 500, while ancestors use tertiary color and weight 400. Hovering a combined control for 150ms opens its direct-parent catalog, with a short crossing grace for the portaled menu; ArrowDown remains the keyboard entry path. Clicking an ancestor cancels pending hover, closes an open catalog, and only navigates upward. Each direct-parent catalog enables sibling switching and bolds its selected row; its label overrides the optional session-summary title, and a missing switcher catalog loads on interaction. Only the current subagent appends its own direct-child count control. Long titles truncate before the fixed chevron. The trigger reports the direct catalog's total and running counts. Ordinary sidebar rows hide subagent-origin Sessions and read their direct running-child count from the same loaded catalog map; Session summaries supply activity but never create membership. Running direct children use the shared tertiary-grey ongoing loader. Pending interaction outranks parent running; either remains primary while direct-child activity becomes a second hover and assistive status. An ordinary Workspace row with a pending approval, plan review, or question replaces its relative time with the compact label `Approval`, `Plan review`, or `Answer`; hover and assistive details retain the full status and relative time. With neither primary state present, direct-child activity outranks an unviewed completion reminder, which returns after the last running direct child stops. A tree row remains expandable while its child catalog is absent, loading, or failed, and becomes a known leaf only after that catalog loads empty. Loading shows a generic notice rather than summary-derived placeholder rows. The tree presents continuable and one-shot rows, falling back to the Session id when an optional one-shot label is absent. -`running` means the exact child Agent driver is draining work at the Host sampling boundary; `inactive` means that driver is idle or absent. The UI does not translate either value into success, failure, cancellation, completeness, or resumability. `subagent.list` supplies the current driver-status baseline, `host/session-status` updates known activity in place, request-local replay prevents an older in-flight list response from overwriting a newer transition, and `host/session-removed` returns a known row to `inactive`; reconnect reads a fresh baseline. A `host/session-added` frame for a direct subagent immediately flips any loaded parent row to `hasChildren: true`, and that positive hint survives an older in-flight catalog response; membership, labels, mode, diagnostics, and the authoritative snapshot still require a debounced `subagent.list` refresh while the affected branch is open. A prompt response remains delivery-time authority. +`running` means the child Agent driver is draining work; `inactive` means that driver is idle or absent. Session-list baselines and status events supply activity, and removal marks completed subagents inactive while retaining their display projections. The shared parent `subagentCatalog` projection supplies membership. Initial reads and pushed values meet in one projection store; a newer sequence wins. [The projection-consumer decision](../simplification/2026-09-08-web-subagent-catalog-projections.md) owns loading, reconnect, and synchronization tradeoffs. A prompt response remains delivery-time authority. Healthy rows reuse the standard session projections retained in the list mirror. The token figure sums the four disjoint `tokenUsage` buckets across the durable log. `subagentTiming` resets at every descriptor so an inherited fork seed cannot enter the child's total, accumulates completed `turn/start` → `turn/end` spans, and carries same-cut `active.since` and `active.through` bounds for an open turn. Existing session events advance `active.through` while that turn remains open; the menu adds no separate timer or log read and advances its local clock only while a known descendant is running. Below one day it formats whole seconds; longer visual values retain at most two adjacent units, using approximate 30-day months and 365-day years, while hover and accessible naming preserve the exact day/hour/minute/second duration. An inactive row bounds an interrupted open turn with `active.through`, so a stale projection never borrows newer session metadata and reopening the menu never restarts completed work. Neither metric implies a durable outcome. @@ -53,17 +53,17 @@ Agent-bound auxiliary controls are unavailable in addressed child views. In part ## Host adapter and wire contract -`@deepseek-ai/dsh-subagent` owns the browser-safe generated `subagent` Remote namespace: +The Session Controller owns catalog and history reads; `@deepseek-ai/dsh-subagent` owns continuation controls: -- `subagent.list` takes `parentSessionId`, calls `ctx.subagents.listChildren(parentSessionId, signal)`, returns the complete ordered entries with each healthy row's boolean `hasChildren` snapshot, replaces each healthy row's corpus activity with whether its exact Agent driver is running, and includes whether the exact parent currently resolves from `ctx.agents`. -- `subagent.history` takes the full mode-bearing address plus ordinary page arguments. It verifies the child and mode against the direct catalog, reads through `ctx.sessionQuery.readSession()`, rechecks direct lineage, and returns the ordinary raw-event, render-intent, pagination, and host-computed session-projection baseline without publishing an Agent. +- `session.projections` takes `sessionId` and returns one live-preferred Session observation’s complete projection baseline without activating an Agent. The Client seeds the standard projection store; subagent consumers select `subagentCatalog`. Parent Agent availability comes from Session-list summaries and lifecycle events. +- `session.page` and `session.follow` take the full mode-bearing address. They validate the child header, direct parent, descriptor identity, and mode at the observed cut, then return ordinary raw events, pagination, live reconciliation, and Host projection baselines without publishing an Agent. - `subagent.prompt` accepts only a `mode: 'continuable'` address, `delivery: 'queue' | 'steer'`, and upload-shaped `PromptContentPart[]`; the Host admits and persists image parts into durable references before delivery ([image delivery](../../archived/bug-fix/2026-08-27-steer-followup-image-delivery.md)). It requires the exact live parent, revalidates the catalog address, uses the continuation manager's shared human-delivery admission, and returns the accepted `MessageId`. -The gateway maps missing parent, missing or diagnostic catalog entries, not-resumable and unauthorized children, request cancellation, image admission and image-capability refusals (`subagent/attachment-invalid`), and temporarily unavailable continuation admission to typed RPC errors. It does not expose descriptor or provider details. A list/prompt race is normal: the prompt result, not the earlier availability or activity snapshot, is authoritative. +The gateway maps missing parents or catalog entries, not-resumable and unauthorized children, request cancellation, image admission and image-capability refusals (`subagent/attachment-invalid`), and temporarily unavailable continuation admission to typed RPC errors. It does not expose descriptor or provider details. A list/prompt race is normal: the prompt result, not the earlier availability or activity snapshot, is authoritative. -Viewing persisted history creates no mux subscription by itself. When a follow-up materializes a cold child Activation, the existing Host and mux streams publish its lifecycle and events. Reconnect rebuilds the addressed window through `subagent.history`. +Viewing persisted history creates no Agent by itself. When a follow-up materializes a cold child Activation, the existing Host and Session journal streams publish its lifecycle and events. Reconnect rebuilds the addressed window through `session.follow`. -The ordinary `session.history` route is likewise observation-only for both ordinary and subagent sessions, but it does not carry the catalog address or grant continuation authority. Every ordinary route that needs an Agent resolves through the shared ownership fence before cold resume; `session.cancel` retains that fence. `session.updateQueue` has one target-local exception for a live child whose current projected identity is continuable and comes from its own non-seed suffix; one-shot, missing, unknown, corrupt, seed-only, or cold children remain fenced. +The ordinary `session.page` and `session.follow` address is likewise observation-only for both ordinary and subagent sessions, but it does not carry the catalog address or grant continuation authority. Every ordinary route that needs an Agent resolves through the shared ownership fence before cold resume; `session.cancel` retains that fence. `session.updateQueue` has one target-local exception for a live child whose current projected identity is continuable and comes from its own non-seed suffix; one-shot, missing, unknown, corrupt, seed-only, or cold children remain fenced. The adapter stays behind the generated Remote namespace; `dsh-host-webserver` remains a carrier. Browser code imports the contract through the existing connection package and never reaches host `ctx`, preserving the [archived GUI RPC layering decision](../../archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.md). @@ -73,7 +73,7 @@ The React-free runtime owns catalogs, single-flight refreshes, retained addresse Catalogs ride the standard `useSessions` snapshot. Component-local state owns menu visibility, expanded branches, focus, and hover timers. `ui-conversation` declares a lineage slot for the current ordinary title and every subagent breadcrumb, passes plain breadcrumb identity and display text plus an upward-navigation callback for ancestors, and retains the ordinary title as the render fallback. `@deepseek-ai/dsh-client-ui-subagent` occupies each lineage slot with direct-parent catalog navigation and elects a reason-specific read-only composer from ordinary owner props. Components receive derived props and callbacks, never `ctx`. -Every in-process subagent child stamps `SessionHeader.origin: 'subagent'` before publication. Session list summaries and incremental Host frames project it so grouped and flat sidebars omit duplicate child rows while preserving ordinary forks. The same existing `host/session-added` frame marks a loaded direct parent row expandable without introducing a catalog event stream. Descriptor mode and catalog verification remain the authority for navigation, continuation, and authorization. +Every in-process subagent child stamps `SessionHeader.origin: 'subagent'` before publication. Session list summaries and incremental Host frames project it so grouped and flat sidebars omit duplicate child rows while preserving ordinary forks. Parent catalog projection owns membership and tree structure; descriptor identity and exact-parent checks own addressed history and continuation validation. The package's existing `@label` source remains separate plain-text model input. It does not resolve labels to addresses or acquire continuation semantics. @@ -97,23 +97,23 @@ The shipped Web composition mounts SQLite session query beside JSONL persistence **Infer mode or sidebar filtering from lineage.** Rejected because ordinary forks share `parentSession`. The descriptor-backed catalog owns mode; the separate `origin` marker is only a cheap navigation classifier. -**Build an eager recursive tree or dedicated catalog stream.** Rejected for the current scale. Header-only one-level expandability lookahead preserves pre-click stability without reading descendant events, while disclosure remains a lazy authoritative direct-child read; existing Host frames update activity, restore expandable parent rows, and trigger bounded membership refreshes. +**Build an eager recursive tree or dedicated catalog stream.** Rejected for the current scale. Disclosure loads missing catalogs lazily, and existing control frames carry complete projection updates. **Let a child remain independently interactive after its parent disappears.** Rejected because independent lifetime and user ownership require side-session semantics. ## Testing -- Host protocol tests pin schemas including required boolean expandability, id echoing, mode verification, non-activating history, exact-parent enforcement, FIFO admission receipts, cancellation, and sanitized failure mapping. +- Host protocol tests pin healthy direct catalog schemas, id echoing, mode verification, non-activating history, exact-parent enforcement, FIFO admission receipts, cancellation, and sanitized failure mapping. - Generic Host tests pin attached and cold history and forks without Agent publication, cold projection folding, descriptor/origin/runtime-owner denial, explicit-id adoption denial, and the direct queue-control fence. -- Client object tests pin retained and restored addresses, one-shot read-only and cancel rejection, history routing, continuable prompt and interrupt routing, suppression of Agent-bound model controls, live activity flips including in-flight response replay and detach fallback, subagent-parent expandability flips, and membership refresh. -- jsdom tests pin the ordinary-title separator, per-level combined subagent-title switchers, 12px nested titles, current and ancestor styling, selected-row weight, catalog-label precedence, hover delay, upward-click suppression, truncation with a retained chevron, the aggregate descendant count and activity, sidebar propagation across nested lineage and ordinary-fork boundaries, row-status precedence, token totals, second-precision running and frozen inactive durations, adaptive long-duration units with exact accessible text, the summary-backed root action across absent and stale-empty catalogs, known loading-row shape, mixed-mode rows, pre-click leaf disclosure, diagnostics, lazy descendant disclosure, direct-parent addresses, keyboard behavior, and both read-only reasons. -- The keyless assembled Web snapshot contains an inactive continuable child with durable usage, an inactive one-shot sibling with a deterministic long duration, and a persisted grandchild; it pins the three-descendant trigger across a stale empty catalog response, usage and timing rows, adaptive long-duration presentation, and the aggregate running transition, expands without activation, opens persisted history, admits a human FIFO follow-up, reconciles child mux events, and proves one-shot history remains read-only. A separate assembled scenario holds a real child Agent turn at the LLM seam while it pins the aggregate running state in both the header and visible idle owner row, then cancels the turn during teardown. +- Client object tests pin retained and restored addresses, one-shot read-only and cancel rejection, history routing, continuable prompt and interrupt routing, suppression of Agent-bound model controls, live activity from Session summaries and Agent disposal, authoritative catalog membership, and membership refresh. +- jsdom tests pin the ordinary-title separator, per-level combined subagent-title switchers, 12px nested titles, current and ancestor styling, selected-row weight, catalog-label precedence, hover delay, upward-click suppression, truncation with a retained chevron, direct counts and activity from catalogs, sidebar direct-child activity, row-status precedence, token totals, second-precision running and frozen inactive durations, adaptive long-duration units with exact accessible text, generic loading, mixed-mode rows, ready-empty leaf detection, lazy descendant disclosure, direct-parent addresses, keyboard behavior, and both read-only reasons. +- The keyless assembled Web snapshot contains an inactive continuable child with durable usage, an inactive one-shot sibling with a deterministic long duration, and a persisted grandchild; it pins direct catalog counts, usage and timing rows, adaptive long-duration presentation, and lazy nested expansion, opens persisted history without activation, admits a human FIFO follow-up, reconciles child mux events, and proves one-shot history remains read-only. A separate assembled scenario holds a real child Agent turn at the LLM seam while it pins the direct running state in both the header and visible idle owner row, then cancels the turn during teardown. - Navigation tests pin subagent-only breadcrumbs, workspace placement for forks created from subagents, and `origin: 'subagent'` sidebar filtering without hiding ordinary forks. ## Consequences -- Catalog reads may rescan persisted lineage and each direct candidate's descriptor log, but expandability reuses only descendant headers already present in that trace; the Web activity baseline adds one Agent-registry lookup per healthy row and then uses existing live frames, while usage and duration reuse projection baselines and pushes with no per-row log read, and membership refresh stays debounced and single-flight. -- Parent availability, child activity, and `hasChildren` are snapshots. Publication, disposal, another sender, or another process may win after listing; typed prompt failure remains expected. +- Catalog reads fold only the selected parent's catalog projection. Web activity comes from Session summaries, while usage and duration reuse projection baselines and pushes with no per-row log read; projection reads remain single-flight. +- Parent availability and child activity are snapshots. Publication, disposal, another sender, or another process may win after listing; typed prompt failure remains expected. - A child may publish between history fetch and mux subscription, so the existing sequence reconciliation also covers the cold-to-live addressed path. - Persisted origin adds one deliberately weak product-classification field to child headers and list projections; it cannot become an authorization shortcut. - Beyond the current-turn Stop of a running continuable child ([interrupt contract](2026-08-06-continuable-subagent-interrupt.md)), the UI has no child cancellation, durable outcome, Activation identity, deletion, or independently interactive offline mode, and its text must not imply those capabilities. Active-turn duration measures logged work rather than Activation residency. diff --git a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md index 30c41f0370..4531528dd2 100644 --- a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md +++ b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md @@ -10,13 +10,13 @@ Status: implemented 浏览器必须遵守[可继续 subagent 约定](../../implemented/feature/2026-07-28-continuable-subagent-conversations.zh.md):一个可继续 child 在进程内最多只能有一项 Activation,只能通过确切的存活直接 parent 接受后续工作,并将 agent inbox 用作唯一的 FIFO。查看历史不得创建 Activation。inbox 消息一经接受,HTTP 调用方既不拥有其执行过程,也不会获得取消句柄。 -UI 还必须保留[持久化目录](../../archived/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md)的成员、mode 与 diagnostic。共享服务报告采用实时优先规则的语料活动状态,而 Web 投影会将其替换为确切 child Agent driver 的 `running` 或 `inactive` 状态。这两种活动状态都不是持久化结果,也不承诺继续执行会成功。 +UI 还必须保留[持久化目录](../architecture/2026-09-01-parent-owned-subagent-catalog.zh.md)的成员与 mode。Web 投影会添加确切 child Agent driver 的 `running` 或 `inactive` 状态。这两种活动状态都不是持久化结果,也不承诺继续执行会成功。 ## 决策 Web 产品通过页头的当前 title 谱系区域公开选中会话中由会话支撑的直接 subagent。用户可以懒加载展开后代目录,并在现有对话区域中打开任一 mode。one-shot child 永久只读。可继续 child 只有在其确切直接 parent agent 存活时才接受用户后续消息;否则,其持久化 transcript 仍然可读,并附带恢复说明。 -同一个页头行还可以把 child 作为 `dsh-resource://chat/session/?parent=&mode=` 在右侧 Sidebar 打开。打开时优先使用独立分栏;无法分栏时回退到当前分栏。Sidebar tab 使用共享 Conversation Component Factory 渲染并省略宽度控制,因此主对话与嵌入式对话共用一套组装,而不共享布局界面。 +同一个页头行还可以把 child 作为 `dsh-resource://subagentchat/session/?parent=&mode=` 在右侧 Sidebar 打开。打开时优先使用独立分栏;无法分栏时回退到当前分栏。Sidebar tab 使用共享 Conversation Component Factory 渲染并省略宽度控制,因此主对话与嵌入式对话共用一套组装,而不共享布局界面。 每个打开的 child 都携带目录派生地址 `{ parentSessionId, childSessionId, mode }`。选择专用历史与提示词传输的是包含 mode 的地址,而不是谱系或粗粒度 origin 标记。历史操作会从持久化存储读取会话,而不触发激活。可继续提示词通过 `subagent.prompt` 携带 Queue 或 Steer 投递,并在 inbox 接受消息时以 `{ messageId }` 成功返回;它不会公开 Activation、等待完成或返回结果。相邻 Agent 的模型消息使用单独拥有的固定 Steer 操作。 @@ -32,16 +32,16 @@ Figma 中的 [subagent 列表](https://www.figma.com/design/jRBBK7zBgcszdVWQ0Fh5 | 设计意图 | 已交付约定 | | --- | --- | -| 会话页头可打开紧凑的 child 列表。 | 触发器会汇总仅含 subagent 的完整后代谱系;树按服务顺序显示每个直接目录条目,包括已禁用的 diagnostic。 | +| 会话页头可打开紧凑的 child 列表。 | 触发器统计 parent catalog service 返回的健康直接条目。 | | 选择一行会复用对话 UI。 | 已寻址历史绝不激活 child;只有 parent 存活的可继续行才保留普通输入框。 | -| 嵌套 agent 会逐层展开。 | 每行携带一层 `hasChildren` 快照;展开时会立即预留已知直接后代行,随后仍只加载该行的直接目录,并保留其自身的 parent 地址。 | +| 嵌套 agent 会逐层展开。 | row 在自身 catalog 成功加载为空前保持可展开;展开时只加载该直接 catalog,并保留 row 的 parent 地址。 | | 条目显示 label、状态、token 用量与活跃耗时,同时避免侧边栏条目重复。 | mode 与 `running`/`inactive` 活动状态会同时以文字和视觉呈现;可选 title、持久化 token 用量与活跃轮次耗时来自列表保留的投影值。紧凑耗时从一天起省略更小的单位,而悬停和无障碍名称仍保留精确的整秒数。`SessionHeader.origin` 会移除重复的导航条目,但不授予任何能力。 | ## 产品约定 -只有当完整的直接目录空响应与会话摘要投影相符,二者均表明没有已知的 subagent 后代时,才不显示后代数量控件。普通会话会用斜杠分隔当前 title 和该数量控件。每一级 subagent 面包屑都将紧凑的 12px title 与固定显示的双向箭头组合成一个控件:当前面包屑使用主标签颜色和 500 字重,祖先则使用三级标签颜色和 400 字重。悬停组合控件 150ms 后会打开其直接 parent 目录;浮层菜单具有短暂的跨越宽限时间,ArrowDown 保留为键盘入口。点击祖先会取消待触发的悬停、关闭已打开的目录,并且只向上导航。每个直接 parent 目录都可切换 sibling,并会加粗其选中行;目录 label 优先于会话摘要 title,缺失的每个切换器目录都会自动刷新。只有当前 subagent 会追加自己的后代数量控件。过长的 title 会在固定箭头之前截断。数量触发器会统计经不间断的 `origin: 'subagent'` 谱系可达的每个已知会话摘要后代,在普通 fork 处停止,并在任一计入统计的后代处于 `running` 时显示活动仍在进行。由于普通侧边栏行会隐藏 origin 为 subagent 的会话,Workspace 浏览器会在每个可见的普通行上索引同一条不间断谱系:任何运行中的后代都会让该行显示共享的三级灰色 ongoing loading,并在悬停与无障碍文本中给出确切数量,同时不会把空闲 parent 描述为正在运行。普通 fork 会开启单独的聚合子树。待处理交互优先于 parent 的运行中状态;二者无论哪一项存在都会保持为主要状态,而后代活动则成为悬停与无障碍状态中的第二项。普通 Workspace 行存在待处理的审批、计划审阅或问题时,会用紧凑的「待批准」「计划待审」或「待回答」替换相对时间;悬停与无障碍详情仍保留完整状态和相对时间。两者均不存在时,后代活动优先于未查看的完成提醒;最后一个运行中的后代停止后,该提醒会恢复。每个健康的直接目录行都携带读取时的 `hasChildren` 提示,该值只根据持久化 `origin: 'subagent'` 的直接谱系 header 派生;正常的健康与 diagnostic subagent 候选都会携带该标记,而普通 fork 不会。该预查不读取任何后代事件日志,展开后仍以描述符支撑的目录为权威依据。当摘要在该目录尚不存在时或在一次陈旧的空响应后确认已有后代时,该操作会保持可见,并且在打开它以刷新目录之前仅显示禁用的加载行;仅由摘要支撑的行绝不会提供导航能力。UI 会在交互前就省略已知叶子节点的展开控件;该提示不承诺 child 会一直是叶子。已展开的直接目录加载期间,已知谱系会为每个直接后代预留一行禁用的加载行,而不会递归获取后代目录。随后树会呈现可继续与 one-shot 行;one-shot 的可选 label 缺失时,回退到其会话 id。损坏、不受支持或不可用的候选仍以禁用的 diagnostic 行显示。 +直接 catalog 有子项或读取失败时显示 child 数量控件;空目录缺席、加载中或成功读取为空时均隐藏该控件。普通会话会用斜杠分隔当前 title 和该控件。每一级 subagent 面包屑都将紧凑的 12px title 与固定显示的双向箭头组合成一个控件:当前面包屑使用主标签颜色和 500 字重,祖先则使用三级标签颜色和 400 字重。悬停组合控件 150ms 后会打开其直接 parent 目录;浮层菜单具有短暂的跨越宽限时间,ArrowDown 保留为键盘入口。点击祖先会取消待触发的悬停、关闭已打开的目录,并且只向上导航。每个直接 parent 目录都可切换 sibling,并会加粗其选中行;目录 label 优先于可选的会话摘要 title,缺失的切换器目录在交互时加载。只有当前 subagent 会追加自己的直接 child 数量控件。过长的 title 会在固定箭头之前截断。触发器报告直接 catalog 的总数与运行数。普通侧边栏 row 隐藏 origin 为 subagent 的 Session,并从同一份已加载 catalog map 读取直接运行 child 数;Session summary 提供 activity,但绝不创建 membership。运行中的直接 child 使用共享的三级灰色 ongoing loading。待处理交互优先于 parent 的运行中状态;二者无论哪一项存在都会保持为主要状态,而直接 child activity 则成为悬停与无障碍状态中的第二项。普通 Workspace 行存在待处理的审批、计划审阅或问题时,会用紧凑的「待批准」「计划待审」或「待回答」替换相对时间;悬停与无障碍详情仍保留完整状态和相对时间。两种主要状态均不存在时,直接 child activity 优先于未查看的完成提醒;最后一个运行中的直接 child 停止后,该提醒会恢复。tree row 在 child catalog 缺席、加载中或失败时保持可展开,只有 catalog 成功加载为空后才成为已知叶子。加载时显示通用提示,不会从 summary 生成占位 row。tree 会呈现 continuable 与 one-shot row;one-shot 的可选 label 缺失时,回退到其 Session id。 -`running` 表示在 Host 采样边界,确切 child Agent driver 正在处理工作;`inactive` 表示该 driver 空闲或不存在。UI 不会把任一值解释为成功、失败、取消、完成状态或可恢复性。`subagent.list` 提供当前 driver 状态基线,`host/session-status` 会就地更新已知活动状态,请求内回放会阻止更早发起但尚未完成的列表响应覆盖较新的状态转换,`host/session-removed` 则会使已知行恢复为 `inactive`;重连时会读取新的基线。直接 subagent 的 `host/session-added` 帧会立即把任何已加载的 parent 行翻转为 `hasChildren: true`,并使这项正向提示不被更早发起但尚未完成的目录响应覆盖;受影响分支打开期间,成员、label、mode、diagnostic 与权威快照仍需要通过去抖动的 `subagent.list` 刷新来更新。消息投递时仍以提示词响应为权威依据。 +`running` 表示子 Agent driver 正在处理工作;`inactive` 表示该 driver 空闲或不存在。Session 列表基线与状态事件提供活动状态,移除事件将完成的子代理标为 inactive 并保留其展示 projection。共享的父 `subagentCatalog` projection 提供成员关系。初始读取与推送值进入同一个 projection store,较新序号优先。[projection 消费决策](../simplification/2026-09-08-web-subagent-catalog-projections.zh.md) 说明加载、重连与同步取舍。提示词响应仍是投递时的权威依据。 健康行会复用列表镜像中保留的标准会话投影。token 用量数值会汇总持久化日志中四个互不重叠的 `tokenUsage` 桶。`subagentTiming` 会在每个描述符处重置,使继承的 fork 种子不会计入 child 总量;它会累加已完成的 `turn/start` → `turn/end` 时段,并携带未结束轮次同一切面的 `active.since` 和 `active.through` 边界。该轮次保持未结束期间,现有会话事件会推进 `active.through`;菜单不会增加单独的计时器或日志读取,且仅在有已知后代处于运行状态时才推进其本地时钟。不足一天时,菜单会以整秒格式化时间;达到一天后的视觉值最多保留两个相邻单位,其中月份按近似 30 天计算,年份按近似 365 天计算,而悬停信息与无障碍名称会保留精确的天/小时/分钟/秒耗时。对 inactive 行,菜单以 `active.through` 为被中断未结束轮次的上界,因此陈旧投影绝不会借用更新的会话元数据,且重新打开菜单绝不会让已完成工作重新计时。这两项指标都不蕴含持久化结果语义。 @@ -53,17 +53,17 @@ one-shot 行始终会用文案替代输入框,说明执行记录为只读。 ## 宿主适配器与协议约定 -`@deepseek-ai/dsh-subagent` 拥有浏览器安全的生成 `subagent` Remote 命名空间: +Session Controller 负责 catalog 与 history read;`@deepseek-ai/dsh-subagent` 负责 continuation control: -- `subagent.list` 接受 `parentSessionId`,调用 `ctx.subagents.listChildren(parentSessionId, signal)`,返回完整有序的条目以及每个健康行的布尔 `hasChildren` 快照,把每个健康行的语料活动状态替换为其确切 Agent driver 是否正在运行,并说明当前能否从 `ctx.agents` 解析出确切 parent。 -- `subagent.history` 接受包含 mode 的完整地址与普通页参数。它对照直接目录校验 child 与 mode,通过 `ctx.sessionQuery.readSession()` 读取,再次检查直接谱系,并在不发布 agent 的情况下返回普通原始事件、渲染意图、分页与由 Host 计算的会话投影基线。 +- `session.projections` 接受 `sessionId`,返回一次 live-preferred Session observation 的完整 projection 基线,不激活 Agent。Client 将基线写入标准 projection store;subagent 消费者选择 `subagentCatalog`。父 Agent 可用性来自 Session 列表摘要与生命周期事件。 +- `session.page` 与 `session.follow` 接受包含 mode 的完整地址。它们在观察到的 cut 上校验 child header、直接 parent、descriptor identity 与 mode,随后在不发布 Agent 的情况下返回普通 raw event、pagination、live reconciliation 与 Host projection baseline。 - `subagent.prompt` 只接受 `mode: 'continuable'` 地址、`delivery: 'queue' | 'steer'` 与上传形态的 `PromptContentPart[]`;Host 在投递前把图片部分准入并持久化为持久引用([图片投递](../../archived/bug-fix/2026-08-27-steer-followup-image-delivery.md))。它要求确切的存活 parent,重新校验目录地址,使用 continuation manager 共享的人类投递准入,并返回已接受的 `MessageId`。 -网关会将 parent 缺失、目录条目缺失或为 diagnostic、child 不可恢复或未授权、请求取消、图片准入或图片能力拒绝(`subagent/attachment-invalid`)以及继续执行准入暂时不可用等失败映射为类型化 RPC 错误。它不会公开描述符或提供方细节。list/prompt 竞态属于正常情况:权威依据是提示词操作的结果,而不是更早的可用性或活动快照。 +网关会将 parent 或目录条目缺失、child 不可恢复或未授权、请求取消、图片准入或图片能力拒绝(`subagent/attachment-invalid`)以及继续执行准入暂时不可用等失败映射为类型化 RPC 错误。它不会公开描述符或提供方细节。list/prompt 竞态属于正常情况:权威依据是提示词操作的结果,而不是更早的可用性或活动快照。 -查看持久化历史本身不会创建 mux 订阅。当后续消息物化冷态 child Activation 时,现有 Host 与 mux 流会发布其生命周期与事件。重新连接时,系统通过 `subagent.history` 重建已寻址窗口。 +查看持久化历史本身不会创建 Agent。当后续消息物化冷态 child Activation 时,现有 Host 与 Session journal stream 会发布其生命周期与事件。重新连接时,系统通过 `session.follow` 重建已寻址窗口。 -普通 `session.history` 路由对于普通会话和 subagent 会话同样只执行观察,但它既不携带目录地址,也不授予继续执行权限。每条需要 Agent 的普通路由都会在恢复冷会话前经过共享所有权栅栏;`session.cancel` 保留该栅栏。`session.updateQueue` 只有一个目标本地例外:目标是在线 child,且其当前 projection identity 为 continuable 并来自自身的非 seed suffix;one-shot、缺失、未知、损坏、仅含 seed identity 或冷 child 仍受栅栏阻挡。 +普通 `session.page` 与 `session.follow` 地址对于普通会话和 subagent 会话同样只执行观察,但它既不携带目录地址,也不授予继续执行权限。每条需要 Agent 的普通路由都会在恢复冷会话前经过共享所有权栅栏;`session.cancel` 保留该栅栏。`session.updateQueue` 只有一个目标本地例外:目标是在线 child,且其当前 projection identity 为 continuable 并来自自身的非 seed suffix;one-shot、缺失、未知、损坏、仅含 seed identity 或冷 child 仍受栅栏阻挡。 适配器仍位于生成的 Remote 命名空间之后;`dsh-host-webserver` 仍作为载体。浏览器代码通过现有连接包导入约定,绝不直接访问宿主 `ctx`,从而保持[已归档的 GUI RPC 分层决策](../../archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.md)。 @@ -73,7 +73,7 @@ one-shot 行始终会用文案替代输入框,说明执行记录为只读。 目录通过标准 `useSessions` 快照传递。组件局部状态负责菜单可见性、已展开分支、焦点与悬停计时器。`ui-conversation` 为当前普通 title 和每一级 subagent 面包屑声明谱系 slot,传入纯数据形式的面包屑身份与显示文本,并为祖先传入向上导航回调;普通 title 由 render site 保留为回退。`@deepseek-ai/dsh-client-ui-subagent` 以直接 parent 目录导航占用每个谱系 slot,并根据普通 owner props 选择按原因区分的只读编辑器。组件只接收派生 props 与回调,绝不接收 `ctx`。 -每个进程内 subagent child 都会在发布前写入 `SessionHeader.origin: 'subagent'`。会话列表摘要与增量 Host 帧会投影该字段,使分组和扁平侧边栏省略重复的 child 行,同时保留普通 fork。同一条现有的 `host/session-added` 帧还会把已加载的直接 parent 行标记为可展开,而无需引入目录事件流。描述符 mode 与目录校验仍然是导航、继续执行和授权的权威依据。 +每个进程内 subagent child 都会在发布前写入 `SessionHeader.origin: 'subagent'`。会话列表摘要与增量 Host 帧会投影该字段,使分组和扁平侧边栏省略重复的 child 行,同时保留普通 fork。parent catalog projection 拥有 membership 与 tree structure 权威;descriptor identity 与精确 parent check 拥有 addressed history 与 continuation validation 权威。 该包现有的 `@label` source 仍然是独立的面向模型纯文本输入。它不会将 label 解析为地址,也不会获得继续执行语义。 @@ -97,23 +97,23 @@ one-shot 行始终会用文案替代输入框,说明执行记录为只读。 **根据谱系推断 mode 或侧边栏过滤。** 不予采纳,因为普通 fork 共享 `parentSession`。由描述符支撑的目录负责提供 mode;单独的 `origin` 标记只是低成本的导航分类器。 -**构建预先加载的递归树或专用目录流。** 就当前规模而言不予采纳。仅用于页头的一层可展开性预查会在不读取后代事件的情况下保证点击前的稳定性,而展开仍是懒加载式权威直接 child 读取;现有 Host 帧会更新活动状态、恢复 parent 行的可展开性,并触发有界的成员刷新。 +**构建预先加载的递归树或专用目录流。** 就当前规模而言不予采纳。展开控件按需加载缺失目录,现有 control 帧传递完整 projection 更新。 **让 child 在 parent 消失后仍能独立交互。** 不予采纳,因为独立生命周期与用户所有权需要 side session 语义。 ## 测试 -- 宿主协议测试固定 schema(包括必需的布尔可展开性)、id 回显、mode 校验、非激活式历史、确切 parent 强制要求、FIFO 准入回执、取消与脱敏后的失败映射。 +- 宿主协议测试固定健康的直接 catalog schema、id 回显、mode 校验、非激活式历史、确切 parent 强制要求、FIFO 准入回执、取消与脱敏后的失败映射。 - 通用 Host 测试固定在不发布 Agent 的情况下读取已附加与冷态历史及执行 fork、冷态投影归并、按描述符/origin/运行时 owner 拒绝、拒绝显式 id 接纳,以及直接队列控制栅栏。 -- 客户端对象测试固定已保留与已恢复的地址、one-shot 只读与取消拒绝、历史路由、可继续提示词与中断路由、屏蔽绑定到 agent 的模型控件、实时活动状态翻转(包括在途响应回放与 detach 回退)、subagent parent 可展开性翻转与成员刷新。 -- jsdom 测试固定普通 title 分隔符、逐级合并的 subagent title 切换热区、嵌套 title 的 12px 字号、当前与祖先样式、选中行字重、目录 label 优先级、悬停延迟、向上点击抑制、保留箭头的截断、后代聚合计数与活动状态、侧边栏活动在嵌套谱系中的传播与普通 fork 边界、行状态优先级、token 用量总计、精确到秒的运行中耗时与冻结后 inactive 耗时、采用自适应单位的长耗时及其精确无障碍文本、目录缺失或为陈旧空目录时由摘要支撑的根操作、已知加载行的形态、混合 mode 行、点击前的叶子展开控件、diagnostic、后代懒加载展开、直接 parent 地址、键盘行为与两种只读原因。 -- 无密钥的组装 Web 快照包含一个具有持久化 token 用量的 inactive 可继续 child、一个具有确定性长耗时的 inactive one-shot sibling 和一个持久化 grandchild;它会固定触发器在一次陈旧的空目录响应后仍显示三个后代,并固定 token 用量与计时行、自适应长耗时呈现及聚合 `running` 状态转换,在不激活的情况下展开、打开持久化历史、准入一条用户 FIFO 后续消息、归并 child mux 事件,并证明 one-shot 历史仍然只读。另一个独立的组装场景会在 LLM seam 处保持一个真实的 child Agent 轮次进行中,同时固定页头和可见空闲 owner 行中的聚合运行状态,随后在 teardown 期间取消该轮次。 +- 客户端对象测试固定已保留与已恢复的地址、one-shot 只读与取消拒绝、历史路由、可继续提示词与中断路由、屏蔽绑定到 agent 的模型控件、来自 Session 摘要与 Agent 销毁的实时活动状态、权威 catalog membership 与成员刷新。 +- jsdom 测试固定普通 title 分隔符、逐级合并的 subagent title 切换热区、嵌套 title 的 12px 字号、当前与祖先样式、选中行字重、目录 label 优先级、悬停延迟、向上点击抑制、保留箭头的截断、catalog 直接计数与 activity、侧边栏直接 child activity、行状态优先级、token 用量总计、精确到秒的运行中耗时与冻结后 inactive 耗时、采用自适应单位的长耗时及其精确无障碍文本、通用加载提示、混合 mode row、ready-empty 叶子判定、descendant 懒加载展开、直接 parent 地址、键盘行为与两种只读原因。 +- 无密钥的组装 Web 快照包含一个具有持久化 token 用量的 inactive 可继续 child、一个具有确定性长耗时的 inactive one-shot sibling 和一个持久化 grandchild;它会固定直接 catalog 数量、token 用量与计时行、自适应长耗时呈现及嵌套懒加载,在不激活的情况下打开持久化历史、准入一条用户 FIFO 后续消息、归并 child mux 事件,并证明 one-shot 历史仍然只读。另一个独立的组装场景会在 LLM seam 处保持一个真实的 child Agent 轮次进行中,同时固定页头和可见空闲 owner row 中的直接运行状态,随后在 teardown 期间取消该轮次。 - 导航测试固定仅含 subagent 的面包屑导航、从 subagent 创建 fork 时的 Workspace 归属,以及 `origin: 'subagent'` 侧边栏过滤,同时不隐藏普通 fork。 ## 后果 -- 目录读取可能重新扫描持久化谱系与每个直接候选的描述符日志,但可展开性只复用该追踪中已有的后代 header;Web 活动基线会为每个健康行增加一次 Agent 注册表查找,随后使用现有实时帧,而 token 用量与耗时会复用投影基线和推送,无需按行读取日志,成员刷新则保持去抖动和单次并发。 -- parent 可用性、child 活动状态与 `hasChildren` 都是快照。列出之后,发布、dispose(资源释放)、其他发送方或其他进程都可能抢先改变状态;类型化提示词失败仍属预期行为。 +- catalog read 只 fold 所选 parent 的 catalog projection。Web activity 来自 Session 摘要;token 用量与耗时复用 projection baseline 和 push,无需按 row 读取日志,投影读取保持 single-flight。 +- parent 可用性与 child activity 都是快照。列出之后,发布、dispose(资源释放)、其他发送方或其他进程都可能抢先改变状态;类型化提示词失败仍属预期行为。 - child 可能在历史获取与 mux 订阅之间发布,因此现有序号归并也涵盖从冷态转为存活的已寻址路径。 - 持久化 origin 会为 child header 与列表投影添加一个有意保持弱约束的产品分类字段;它不能变成授权捷径。 - 除对正在运行的可继续 child 的当前轮次 Stop([中断约定](2026-08-06-continuable-subagent-interrupt.zh.md))之外,UI 不提供 child 取消、持久化结果、Activation 身份、删除或可独立交互的离线 mode,其文案不得暗示这些能力已经存在。活跃轮次耗时度量的是已记录工作,而非 Activation 驻留时间。 diff --git a/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml new file mode 100644 index 0000000000..792f97a11a --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.md +2026-08-18-arbitrary-seq-session-fork.md: c02ba6c1f24462224cb7f4f245d82063f29c4d61 +2026-08-18-arbitrary-seq-session-fork.zh.md: fe78e505313b2177435abd93e1d8056972b2646b diff --git a/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.md b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.md new file mode 100644 index 0000000000..c02ba6c1f2 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.md @@ -0,0 +1,39 @@ +# Agent Note: Exact-event session forks with shared crash repair + +Status: implemented + +English | [中文](2026-08-18-arbitrary-seq-session-fork.zh.md) + +## Problem + +A branch may need the history before a tool result arrives, including a historical position in a parent that has since completed. Restricting forks to completed turns prevents that choice. Reusing crash-recovery result wording would falsely imply that the parent was interrupted. + +## Decision + +`SessionStore.fork` accepts any existing integer event seq exactly. It owns source membership, child identity and cut validation. `buildForkSeed`, the only export of `dsh-session/fork`, copies the inclusive prefix, inserts the child's inherited `session/end-seed` marker, and closes the open tail. The Host selects and builds from one immutable observation. Omitted `atSeq` means the latest completed turn with its independent tail, stopping before the next turn or queued user input. An explicit seq never moves. + +Fork and crash recovery share the same tool-pairing algorithm. Only an open step receives missing error results before `step/end`; an open turn then receives `turn/end`. Closed steps and turns remain unchanged, including historical failures with missing results. The internal cause selects `forked` versus `interrupted`, deterministic result IDs and model-visible wording. Fork wording describes missing inherited records and warns that the parent may have executed the call after the cut. Retry advice distinguishes read-only or idempotent operations from operations with side effects. + +The inherited marker precedes synthetic closers. `inheritedEventCount` counts only copied parent events; the marker and closers are child-owned and are persisted before agent publication. A constructor accepts this complete seed only when its supplied cut identifies the final inherited marker. Nested forks retain ancestor markers within their copied prefix. `firstLiveSeq` remains the length of the complete constructor input, distinct from durable inheritance. + +V4 admits not-started fork results without changing released V0–V3 validators. Its codec and relationship validator use a private canonical interrupted-result view for this checked variant, then return the original fork ID and message. The V3-to-V4 migration preserves existing events. The `forked` turn-end reason is acknowledged with the finalized V4 header transition. + +This replaces the [completed-turn-only controller policy](../../archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.md). Explicit cuts retain the requested event exactly; omitted cuts retain completed standalone work, including manual compaction replacements, until a core-owned turn or queued-input event begins. Plugins continue to own their brackets; the controller does not classify plugin events. + +## Alternatives considered + +**Move the cut to a completed step.** This changes an explicit historical choice and loses the requested context. Exact cuts with logged closers preserve that context. + +**Repair during request construction.** Model-visible results must be logged, so the seed records them before the model request. + +**Repair calls in closed steps.** Those failures already belong to the parent; this would expand fork into a new historical repair policy and diverge from crash recovery. + +**Expose a Store-dependent fork wrapper.** Store creation rules remain in Store; the pure seed helper needs only event types and the internal closer, avoiding another public entry and a Store file move. + +## Consequences + +Fork closes the selected open tail, not earlier malformed history. Plugins own their unmatched brackets: no `compaction/end` is synthesized. The inherited marker lets compaction recognize an inherited stale start. Parent and child sequence numbers diverge after the cut. For a new fork, `firstLifecycleSeq` starts at the child-owned marker, so telemetry includes synthetic results and closers. Restored Sessions start this lifecycle after their stored prefix; the durable fork cut alone does not identify new capture work. The chat action retains completed-turn selection; finer event selection is backend functionality and adds no side chat. + +## Testing + +Session and repair tests cover exact cuts, both error classifications, closed failed steps, empty histories, plugin brackets and surface replacements. Agent-loop regressions verify the actual next model request, preserved results, turn numbering and no repeated tool execution. Host tests cover live and cold sources, exact rejection and queued-input exclusion. V4 tests round-trip original fork result data, reject malformed results and validate nested forks. The keyless `fork-mid-turn` browser scenario forks a cold recording through HTTP and continues through the composer with the branch wording rendered in its expected output. diff --git a/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.zh.md b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.zh.md new file mode 100644 index 0000000000..fe78e50531 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.zh.md @@ -0,0 +1,39 @@ +# Agent Note:复用崩溃修复的精确事件会话分叉 + +Status: implemented + +[English](2026-08-18-arbitrary-seq-session-fork.md) | 中文 + +## Problem + +分支可能需要工具结果到来之前的历史,包括父会话已经完成后的历史位置。将 fork 限制到已完成轮次会阻止这种选择。复用崩溃恢复的结果文案则会错误暗示父会话已中断。 + +## Decision + +`SessionStore.fork` 精确接受任意已有的整数事件 seq,并拥有源会话归属、子会话标识和切点校验。`dsh-session/fork` 唯一导出的 `buildForkSeed` 复制含切点的前缀,插入子会话的继承 `session/end-seed` 标记,再关闭开放尾部。Host 从同一份不可变观察中选点和构建。省略 `atSeq` 表示最近已完成轮次及其独立尾部,在下一轮次或排队用户输入前停止。显式 seq 永不移动。 + +Fork 与崩溃恢复共用相同的工具配对算法。只有开放步骤会在 `step/end` 前补缺失的错误结果;开放轮次随后补 `turn/end`。已关闭的步骤和轮次保持原样,包括缺少结果的历史失败。内部 cause 选择 `forked` 或 `interrupted`、确定性的结果 ID 及模型可见文案。Fork 文案描述缺少的继承记录,并提醒父会话可能已在切点后执行调用。重试建议区分只读或幂等操作与有副作用的操作。 + +继承标记位于合成结束事件之前。`inheritedEventCount` 只统计复制的父事件;标记与结束事件属于子会话,在 agent 发布前持久化。构造函数仅在给定切点指向最后一个继承标记时接受这种完整 seed。嵌套 fork 在复制前缀中保留祖先标记。`firstLiveSeq` 仍是完整构造输入的长度,与持久继承计数不同。 + +V4 接受未启动的 fork 结果,不修改已发布的 V0–V3 校验器。其 codec 和关系校验器为这一经过校验的变体提供内部规范 interrupted-result 视图,再返回原始 fork ID 和消息。V3-to-V4 迁移保留已有事件。`forked` 轮次结束原因与已定稿的 V4 头版本变更一起记录兼容性确认。 + +本决策取代[仅按已结束轮次截取的 Controller 策略](../../archived/bug-fix/2026-09-11-session-controller-fork-turn-cut.md)。显式切点精确保留所选事件;省略切点时保留已完成的独立操作,包括手动压缩的替换事件,直到 core 所属的新轮次或排队输入事件开始。插件继续负责自己的括号关系;Controller 不对插件事件分类。 + +## Alternatives considered + +**将切点移到已完成步骤。** 这会改变显式历史选择,丢失所需上下文。精确切点加已记录的结束事件保留该上下文。 + +**构建请求时修复。** 模型可见结果必须进入日志,因此 seed 在模型请求之前记录它们。 + +**修复已关闭步骤中的调用。** 这些失败原本属于父会话;这会将 fork 扩展为新的历史修复策略,偏离崩溃恢复行为。 + +**公开依赖 Store 的 fork 包装函数。** Store 的创建规则留在 Store;纯 seed helper 只需要事件类型和内部结束函数,避免增加公开入口或搬迁 Store 文件。 + +## Consequences + +Fork 关闭所选开放尾部,不修复更早的畸形历史。插件拥有其未配对括号:不会合成 `compaction/end`。继承标记让 compaction 识别继承而来的陈旧 start。父子序号在切点后分离。 新 fork 的 `firstLifecycleSeq` 从子会话自有标记开始,因此 telemetry 包含合成结果与结束事件。恢复的 Session 从已存储前缀之后开始当前生命周期;仅凭持久化 fork 切点无法识别新的采集内容。聊天操作保留已完成轮次选择;更细的事件选择属于后端功能,不增加 side chat。 + +## Testing + +Session 和 repair 测试覆盖精确切点、两种错误分类、已关闭失败步骤、空历史、插件括号和 surface 替换。Agent-loop 回归验证实际的下一次模型请求、结果保留、轮次编号及不重复执行工具。Host 测试覆盖实时与冷源会话、精确拒绝和排队输入隔离。V4 测试往返原始 fork 结果数据、拒绝畸形结果并验证嵌套 fork。无需密钥的 `fork-mid-turn` 浏览器场景通过 HTTP 对冷录制进行 fork,再通过输入框继续运行,并在预期输出中展示分支文案。 diff --git a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml index 2a7ae98b1e..da8a49ddb6 100644 --- a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.md -2026-09-17-persistent-plan-cards.md: 6959cf39f4e47dbd552ee14af7c1ebc09b52bef6 -2026-09-17-persistent-plan-cards.zh.md: 0c40cb5caf4b77f5d4b5c30cead5567f21b45cfd +2026-09-17-persistent-plan-cards.md: 096c89c7ed3e52293787a2724b0c7231ae3740ae +2026-09-17-persistent-plan-cards.zh.md: 95cce3fed84dd802195b87f593654b7d511933cb diff --git a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.md b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.md index 6959cf39f4..096c89c7ed 100644 --- a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.md +++ b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.md @@ -12,7 +12,7 @@ A plan review occupies the composer only until the user answers or dismisses it. `ui-plan` accumulates each Turn’s `exit_plan_mode` submissions, including native calls and PTC dispatches. Each invocation contributes a card to the completed Turn’s final artifact area. The `conversation.chat.turnTail` list admits file deliveries and plan cards together. Review dismissal, refusal, and approval do not delete the recorded plans. -The review intent may carry the tool-call identity. The question plugin declares an action slot, and the plan plugin contributes an opener there and on the historical card. When an invocation exists, both open the resource identified by its complete Session address and invocation. Subagent addresses retain the direct parent, child, and mode for snapshot reads, pagination, and reload. Sidebar layout retains that address; the resource provider reads the existing Session history, paging backwards when the invocation is older than the opening window. Its temporary follow closes after the opening snapshot. +The review intent may carry the tool-call identity. The question plugin declares an action slot, and the plan plugin contributes an opener there and on the historical card. When an invocation exists, both open the resource identified by its complete Session address and invocation. Subagent addresses retain the direct parent, child, and mode for snapshot reads, pagination, and reload. The resource address selects the document’s Session, while the mounted Sidebar selects where its preview opens; embedded child conversations do not require a child Sidebar store. Sidebar layout retains that address; the resource provider reads the existing Session history, paging backwards when the invocation is older than the opening window. Its temporary follow closes after the opening snapshot. A review without an invocation opens a temporary address keyed by browser lifetime, Session, and pending request. The sidebar’s existing navigation parameters hold its Markdown without adding another document store or persisting text in layout. Closing and reopening from the pending card supplies the text again; restored tabs without navigation parameters report an expired preview. diff --git a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.zh.md b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.zh.md index 0c40cb5caf..95cce3fed8 100644 --- a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.zh.md +++ b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.zh.md @@ -12,7 +12,7 @@ Status: implemented `ui-plan` 汇总每个回合的 `exit_plan_mode` 提交,覆盖原生调用和 PTC dispatch。每次调用在已完成回合末尾的产物区域贡献一张卡片。`conversation.chat.turnTail` 列表同时容纳文件产物和计划卡片。关闭、拒绝或批准审批都不会删除已记录的计划。 -审批意图可以携带工具调用标识。提问插件声明操作插槽,计划插件在该插槽和历史卡片中提供打开入口。存在调用标识时,两者都打开由完整会话地址和调用标识确定的资源。子会话地址保留直接父级、子会话及运行模式,用于快照读取、分页和刷新恢复。侧边栏布局保留该地址;资源 provider 读取已有会话历史,当调用早于初始窗口时向前分页。临时 follow 在取得初始快照后关闭。 +审批意图可以携带工具调用标识。提问插件声明操作插槽,计划插件在该插槽和历史卡片中提供打开入口。存在调用标识时,两者都打开由完整会话地址和调用标识确定的资源。子会话地址保留直接父级、子会话及运行模式,用于快照读取、分页和刷新恢复。资源地址确定文档所属的会话,当前挂载的侧边栏决定预览打开的位置;嵌入式子对话不需要子会话自己的侧边栏 store。侧边栏布局保留该地址;资源 provider 读取已有会话历史,当调用早于初始窗口时向前分页。临时 follow 在取得初始快照后关闭。 没有调用标识的审批打开临时地址,由浏览器生命周期、会话和待处理请求共同标识。侧边栏已有的导航参数保存 Markdown,无需额外的文档 store,也不把正文持久化到布局中。关闭后从待处理卡片重新打开会再次提供正文;恢复的标签页若缺少导航参数,则显示预览已失效。 diff --git a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml index 238d996567..94e92c9bac 100644 --- a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-11-persistence-type-history.md -2026-09-11-persistence-type-history.md: e51e9d565718a752ad4209010665f244725db102 -2026-09-11-persistence-type-history.zh.md: 10dfd0565c710c2714c8f87dd290eb351c572a90 +2026-09-11-persistence-type-history.md: c7cddea5ecc479a64ad5f24f5447e869779b7f9e +2026-09-11-persistence-type-history.zh.md: 001ce197c4cd12dc64a5e2bd710e39cb2b61f23a diff --git a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.md b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.md index e51e9d5657..c7cddea5ec 100644 --- a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.md +++ b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.md @@ -10,21 +10,25 @@ A persisted event can retain the same payload type expression while a referenced ## Decision -One normalized type model supplies the readable persistence catalog, the complete schema inventory, and transitive per-root digests. Roots identify the logical Session header, the physical JSONL header line, the event envelope, and every repository-declared event. Source locations, alias names, comments, and property order are presentation details outside the digest. Historical records retain source file paths without line numbers because their selected source trees differ from the current checkout. Referenced and recursive types participate in structural comparison; opaque values retain explicit coverage limits. +One normalized type model supplies the readable persistence catalog, the complete schema inventory, and transitive per-root digests. Roots identify the logical Session header, the physical JSONL header line, the event envelope, and every repository-declared event. Source locations, alias names, ordinary comments, and property order are presentation details outside the digest. Explicit compatibility annotations carry fingerprinted policy data under the [source-attribution policy](2026-09-17-persistence-schema-review.md). Historical records retain source file paths without line numbers because their selected source trees differ from the current checkout. Referenced and recursive types participate in structural comparison; opaque values retain explicit coverage limits. The dedicated [persistence-change records](../../../../docs/persistence-changes/README.md) bind acknowledgement to the after digest of each affected root. A generated companion stores complete after schemas. The initial record covers all roots; later records name each root's predecessor. A predecessor's after schema supplies the next before schema. Verification rejects ambiguous history and requires current source to match the terminal recorded state without consulting Git history or remote services. -Automatic classification permits optional body additions, required-to-optional body changes, and ordinary event additions within one version. Other structural changes require a version-bump decision that includes an increasing header version in that record. The [format-version procedure](../../../../docs/cookbook/adding-a-session-format-version.md) continues to own adjacent migration work. Every structural difference requires an explicit record, including additions allowed within the same version. +Automatic classification permits optional body additions, required-to-optional body changes, and ordinary event additions within one version. The scoped [source-attribution policy](2026-09-17-persistence-schema-review.md) also permits qualified new producer kinds when both saved schemas opt in. Other structural changes require a version-bump decision that includes an increasing header version in that record. The [format-version procedure](../../../../docs/cookbook/adding-a-session-format-version.md) continues to own adjacent migration work. Every structural difference requires an explicit record, including additions allowed within the same version. The new document kind preserves the compatibility reasoning and evidence for a historical type transition. Agent Notes retain mechanism-level decisions; they do not become a growing inventory of individual acknowledgements. Machine declarations remain identical across the bilingual pair and are parsed once. Retrospective [release comparisons](../../../../docs/persistence-changes/releases/README.md) use a separate `persistence-release` kind and pinned tag manifest. They retain changed after schemas and reconstruct adjacent releases, including unchanged tags. Earlier releases predate these acknowledgement rules, so their classifications are informational and their observed versions are not rewritten to satisfy a modern version floor. Historical parsing preserves optional surface operations; the current parser and acknowledgement chain remain strict. This separation permits approximate backfills without turning them into authorization for current changes. -The [format references](../../../../docs/persistence-changes/historical-formats/README.md) preserve complete inventories for every historical integer below the writer constant. The current writer retains the existing generated catalog. Coverage is derived from the constant rather than a hand-maintained version manifest, so advancing the writer requires archiving its predecessor. The archive command copies the validated current inventory, retains its root-reachable definitions, removes source line numbers, and refuses to overwrite an existing snapshot. Source checkpoints remain explicit because event additions and optional payload changes can occur within one format; these snapshots do not authorize current changes or claim migration safety. Historical identifiers are retained in machine schemas and exactly generated schema regions, while current terminology checks still cover the surrounding authored prose. +The [format references](../../../../docs/persistence-changes/historical-formats/README.md) preserve complete inventories for every historical integer below the writer constant. The current writer retains the existing generated catalog. Coverage is derived from the constant rather than a hand-maintained version manifest, so advancing the writer requires archiving its predecessor. The archive command copies the validated current inventory, retains its root-reachable definitions, removes source line numbers, and refuses to overwrite an existing snapshot. Source checkpoints remain explicit because event additions and optional payload changes can occur within one format; these snapshots do not authorize current changes or claim migration safety. Historical identifiers and source package paths are retained in machine schemas and exactly generated schema regions, while current terminology and package-path checks still cover the surrounding authored prose and current catalogs. Record commands generate the bilingual catalog and consistency records from repository-owned templates. Authors can supply the two languages' summary, compatibility reasoning, and actual verification evidence as structured input. Generation supplies identifiers, digests, and snapshots; it never invents a compatibility explanation or test result. Structured check output retains a nonzero failure exit status and reports stable change kinds independently of human-readable descriptions. -Explicit update refreshes an unaccepted terminal record without deleting its authored prose. It recomputes the transition against the remaining history and rejects the baseline or any record with dependants. Review acceptance is not a fact available from the tree, so authors preserve accepted records and add successors. +Explicit update refreshes an unaccepted terminal record without deleting its authored prose. It recomputes the transition against the remaining history and rejects the baseline, any record with dependants, or a finalized record. Review acceptance outside finalized checkpoints is not inferred from the tree, so authors preserve accepted records and add successors. + +### Finalized checkpoints + +Finalization records acceptance independently of publication. A terminal record must not reuse its original header increase to authorize another breaking change to already-written data. The [status record](../../../../docs/session-format-status.md#finalization-record) therefore requires a complete compatibility checkpoint: accepted record semantics remain locked, while compatible current-source changes proceed through new records and breaking changes require a higher writer. The existing classifier and unknown-event protocol are unchanged. This adds no runtime field and cannot detect behavior changes hidden behind unchanged declarations. Coordinated edits to the in-tree authority and checkpoint still require review. ## Alternatives considered diff --git a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md index 10dfd0565c..001ce197c4 100644 --- a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md +++ b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md @@ -10,21 +10,25 @@ Status: implemented ## 决策 -一个规范化类型模型提供可读持久化目录、完整 schema 清单和包含传递引用的逐根摘要。根标识逻辑会话头、物理 JSONL 头行、事件封装以及每个仓库内声明的事件。源码位置、别名名称、注释和属性顺序属于摘要之外的展示细节。历史记录保留源码文件路径而不包含行号,因为其选定的源码树与当前工作树不同。被引用类型和递归类型参与结构比较;不透明值保留明确的覆盖限制。 +一个规范化类型模型提供可读持久化目录、完整 schema 清单和包含传递引用的逐根摘要。根标识逻辑会话头、物理 JSONL 头行、事件封装以及每个仓库内声明的事件。源码位置、别名名称、普通注释和属性顺序属于摘要之外的展示细节。历史记录保留源码文件路径而不包含行号,因为其选定的源码树与当前工作树不同。被引用类型和递归类型参与结构比较;不透明值保留明确的覆盖限制。显式兼容性标记依照[消息源归属策略](2026-09-17-persistence-schema-review.zh.md)携带纳入指纹的策略数据。 专用的[持久化变更记录](../../../../docs/persistence-changes/README.zh.md)将确认绑定到每个受影响根的变更后摘要。生成的伴随文件保存完整的变更后 schema。初始记录覆盖所有根;后续记录为每个根指定前驱。前驱的变更后 schema 提供下一次的变更前 schema。验证拒绝有歧义的历史,并要求当前源码匹配最终记录状态,无需查询 Git 历史或远端服务。 -自动分类允许可选事件体新增、事件体属性从必选改为可选,以及普通事件新增保持同一版本。其他结构变更需要升版本决策,并在该记录中包含递增的头部版本。[格式版本流程](../../../../docs/cookbook/adding-a-session-format-version.zh.md)继续负责相邻迁移工作。每个结构差异都需要显式记录,包括允许保持同一版本的新增。 +自动分类允许可选事件体新增、事件体属性从必选改为可选,以及普通事件新增保持同一版本。当双方保存的 schema 均声明支持时,受限的[消息源归属策略](2026-09-17-persistence-schema-review.zh.md)也允许添加符合条件的生产者 kind。其他结构变更需要升版本决策,并在该记录中包含递增的头部版本。[格式版本流程](../../../../docs/cookbook/adding-a-session-format-version.zh.md)继续负责相邻迁移工作。每个结构差异都需要显式记录,包括允许保持同一版本的新增。 新文档类型保留历史类型转换的兼容性说明和证据。Agent Note 保留机制层面的决策,不积累单次确认清单。双语对中的机器声明保持相同,且只解析一次。 回溯性的[发行版本比较](../../../../docs/persistence-changes/releases/README.zh.md)使用独立的 `persistence-release` 类型和固定 tag 清单。它们保留变化后的 schema,并重建相邻版本,包括未变的 tag。早期版本先于这些确认规则,因此其分类只提供信息,观察到的版本号不会为满足当前最低版本要求而被改写。历史解析保留可选的 surface 操作;当前解析器和确认链仍保持严格。这一区分允许近似回填,同时不会将其变成当前变更的授权。 -[格式参考](../../../../docs/persistence-changes/historical-formats/README.zh.md)为低于写入器常量的每个历史整数版本保留完整目录。当前写入器继续使用现有生成目录。覆盖范围由常量推导,而非手工维护的版本清单,因此推进写入器必须归档其前驱。归档命令复制已验证的当前目录,保留从根类型可达的定义,移除源码行号,并拒绝覆盖已有快照。同一格式内可能新增事件或改变可选载荷,因此来源检查点保持明确;这些快照不授权当前变更,也不声称迁移安全。机器 schema 与精确生成的 schema 区间保留历史标识符,当前术语检查仍覆盖周围的人工说明。 +[格式参考](../../../../docs/persistence-changes/historical-formats/README.zh.md)为低于写入器常量的每个历史整数版本保留完整目录。当前写入器继续使用现有生成目录。覆盖范围由常量推导,而非手工维护的版本清单,因此推进写入器必须归档其前驱。归档命令复制已验证的当前目录,保留从根类型可达的定义,移除源码行号,并拒绝覆盖已有快照。同一格式内可能新增事件或改变可选载荷,因此来源检查点保持明确;这些快照不授权当前变更,也不声称迁移安全。机器 schema 与精确生成的 schema 区间保留历史标识符和源码包路径;当前术语与包路径检查仍覆盖周围的人工说明和当前目录。 记录命令从仓库内模板生成双语目录和一致性记录。作者可以将两种语言的概述、兼容性说明和实际验证证据作为结构化输入。生成过程提供标识符、摘要和快照,不编造兼容性说明或测试结果。结构化检查输出保留非零失败退出码,并报告独立于可读描述的稳定变更种类。 -显式更新可刷新尚未接受的末端记录,无需删除其人工说明。它根据剩余历史重新计算转换,并拒绝基线或已有依赖方的记录。审阅接受状态不是目录内可得的事实,因此作者保留已接受记录并添加后继。 +显式更新可刷新尚未接受的末端记录,无需删除其人工说明。它根据剩余历史重新计算转换,并拒绝基线、已有依赖方的记录或已定稿记录。目录不会推断定稿检查点之外的审阅接受状态,因此作者保留已接受记录并添加后继。 + +### 定稿检查点 + +定稿独立于发布事实记录接受状态。末端记录不能复用原有头版本递增,继续授权对已写入数据进行破坏性变更。因此,[状态记录](../../../../docs/session-format-status.zh.md#finalization-record)要求完整兼容性检查点:已接受记录的语义保持锁定,当前源码的兼容变更通过新记录继续,破坏性变更要求更高的写入器版本。现有分类器与未知事件协议保持不变。这不会添加运行时字段,也不能检测未变声明后隐藏的行为变化。对目录内真源与检查点的协同修改仍须审阅。 ## 考虑过的替代方案 diff --git a/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml new file mode 100644 index 0000000000..45223d0f08 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-17-persistence-schema-review.md +2026-09-17-persistence-schema-review.md: 47308a5584b368c99ee849b6d550538ba1856a09 +2026-09-17-persistence-schema-review.zh.md: eaa3c17991b23612753634297993dd3b951259ab diff --git a/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.md b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.md new file mode 100644 index 0000000000..47308a5584 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.md @@ -0,0 +1,39 @@ +# Agent Note: Persistence schema policy and review + +Status: implemented + +English | [中文](2026-09-17-persistence-schema-review.zh.md) + +## Problem + +Structural fingerprints identify changed persistence types, but a fingerprint alone cannot explain a shared change or distinguish a declared reader promise from an assumption about runtime behavior. Names derived from union positions and traversal paths also change when unrelated siblings are added, obscuring the fields a reviewer needs to inspect. + +## Decision + +Inventory format 2 records supported compatibility metadata with the affected property. The metadata names its binding, policy version, literal discriminator, unknown-kind preservation promise, and qualified attribution kinds. Policy-bearing graphs use a separate fingerprint domain; graphs without a bound policy retain format-1 normalization and fingerprints. Inventory versions describe schema tooling, independently of Session format versions. + +The extractor accepts explicit source bindings only at the core-owned source declaration and requires a literal user or developer role at each use. Producer annotations qualify complete wire-kind groups. The classifier permits a qualified new attribution kind only when both saved schemas carry matching promises. Existing kinds remain subject to structural comparison; removals, retroactive qualification, reserved identities, and unrelated breaking changes retain strict classification. Runtime owners establish and test the promised preservation behavior before activating a binding. + +An optional property with no JSON value is normally omitted from the extracted graph. `@persistenceReserved` explicitly retains such a property as optional `never` when a reader forbids its name. A later JSON-valued definition then changes an existing type instead of appearing as an additive optional field. The marker accepts only one argument-free annotation on an optional `never` or `undefined` property and rejects a mapped use that makes the property required or gives it a JSON value. + +Current inventories retain authored names and source locations as descriptive metadata. Structural digests identify types and provide catalog anchors. Catalogs group source alternatives by literal `kind` and retain every `form` alternative, required field, index signature, and link to its complete definition. Bounded array labels describe their elements instead of inheriting the first event that reached the array. Historical references retain their frozen rendering. + +The read-only `persistence-review` command accepts explicit before and after inventories. It matches unchanged schemas by digest and changed alternatives only when literal discriminators identify them uniquely. Ambiguous alternatives remain separate additions and removals. Shared structural evidence lists every affected root, while a separate section preserves the authoritative classifier diagnostics. The [history mechanism](2026-09-11-persistence-type-history.md) continues to own acknowledgement and version requirements. + +## Alternatives considered + +**Ignore all source changes.** A source can carry replay or validation meaning. Explicit, fingerprinted opt-ins constrain the supported exception and leave other changes visible. + +**Use traversal paths as type identities.** Union positions and first-owner paths describe one walk through a graph. Unrelated insertions and shared references can change them without changing the persisted type. + +**Infer renames from similar fields.** Several alternatives can have the same discriminator or similar structure. Keeping ambiguous additions and removals avoids presenting an unsupported correspondence as fact. + +**Replace compatibility checks with a readable diff.** Review explanations group evidence for a human reader. They cannot relax the classifier or replace the in-tree acknowledgement history. + +**Retain every optional-never property.** Unmarked optional-never properties already normalize away in recorded schemas. Changing that rule would alter unrelated fingerprints and historical normalization; explicit reservations retain only the reader-owned prohibition. + +## Consequences + +Declared compatibility promises participate in fingerprints and remain available when comparing historical snapshots. The tooling does not infer or enforce runtime preservation; the owner of an activated binding supplies that behavior. Ordinary comments, labels, and source locations remain outside structural identity. + +Complete nested schema graphs remain stored in each inventory. Stable labels and grouped review output reduce presentation noise without changing that storage encoding or rewriting frozen historical records. The [cookbook](../../../../docs/cookbook/reviewing-persistence-type-changes.md) describes the review command and acknowledgement workflow. diff --git a/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.zh.md b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.zh.md new file mode 100644 index 0000000000..eaa3c17991 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.zh.md @@ -0,0 +1,39 @@ +# Agent Note: 持久化 schema 策略与审阅 + +Status: implemented + +[English](2026-09-17-persistence-schema-review.md) | 中文 + +## 问题 + +结构指纹能标识变化的持久化类型,但单凭指纹无法解释共享变更,也无法区分已声明的读取承诺与对运行时行为的假设。由联合类型位置和遍历路径生成的名称还会因无关分支新增而变化,遮蔽审阅者需要检查的字段。 + +## 决策 + +Inventory format 2 在受影响属性上记录受支持的兼容性元数据。元数据包含绑定、策略版本、字面量判别字段、未知 kind 保留承诺和符合条件的归属 kind。带策略的图使用独立指纹域;没有绑定策略的图保留 format-1 规范化和指纹。Inventory 版本描述 schema 工具,独立于 Session 格式版本。 + +提取器仅接受核心拥有的 source 声明上的显式绑定,并要求每个使用位置具有 user 或 developer 字面量角色。生产者标记对完整 wire-kind 分组赋予资格。仅当双方保存的 schema 携带匹配承诺时,分类器才允许新增符合条件的归属 kind。已有 kind 仍须进行结构比较;删除、追认资格、保留标识和无关破坏性变更继续采用严格分类。运行时所有者在激活绑定前实现并验证承诺的保留行为。 + +没有 JSON 值的可选属性通常从提取图中省略。当读取器禁止某个属性名时,`@persistenceReserved` 将该属性显式保留为可选 `never`。后续允许 JSON 值的定义因此属于已有类型变更,而非新增可选字段。标记仅接受可选 `never` 或 `undefined` 属性上的单个无参数注解,并拒绝将属性变为必选或允许 JSON 值的映射类型使用。 + +当前 inventory 将人工声明名称和源码位置保留为描述性元数据。结构摘要标识类型并提供目录锚点。目录按字面量 `kind` 对消息源分支分组,并保留每个 `form` 分支、必需字段、索引签名及指向完整定义的链接。有界数组标签描述元素,不继承最先到达该数组的事件名称。历史参考保留冻结的渲染方式。 + +只读 `persistence-review` 命令接受显式的变更前后 inventory。它按摘要匹配未变 schema,仅当字面量判别字段唯一标识分支时才匹配变化分支。有歧义的分支保留为独立新增与删除。共享结构证据列出每个受影响根,独立章节保留权威分类器诊断。[历史机制](2026-09-11-persistence-type-history.zh.md)继续负责确认和版本要求。 + +## 考虑过的替代方案 + +**忽略所有 source 变更。** 消息源可能承载回放或校验语义。显式且纳入指纹的选择加入约束受支持的例外,并使其他变更保持可见。 + +**将遍历路径用作类型身份。** 联合类型位置和首个引用者路径描述的是一次图遍历。无关插入和共享引用可能改变它们,而持久化类型并未改变。 + +**从相似字段推断重命名。** 多个分支可能具有相同判别值或相似结构。保留有歧义的新增与删除,避免将缺乏依据的对应关系呈现为事实。 + +**用可读 diff 取代兼容性检查。** 审阅说明为读者归并证据,不能放宽分类器,也不能取代目录内的确认历史。 + +**保留每个 optional-never 属性。** 未标记的 optional-never 属性在已记录 schema 中已经被规范化省略。改变该规则会影响无关指纹和历史规范化;显式保留仅记录读取器拥有的禁止规则。 + +## 影响 + +声明的兼容性承诺参与指纹,并在比较历史快照时保持可用。工具不会推断或强制运行时保留行为;激活绑定的所有者提供该行为。普通注释、标签和源码位置仍处于结构身份之外。 + +每份 inventory 继续存储完整嵌套 schema 图。稳定标签和分组审阅输出减少展示噪音,不改变存储编码,也不重写冻结历史记录。[实操手册](../../../../docs/cookbook/reviewing-persistence-type-changes.zh.md)介绍审阅命令和确认流程。 diff --git a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml index 16094b8d00..a8f49b1780 100644 --- a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md -2026-07-28-remove-synthetic-log-only-turns.md: b35045d036dbb3ea18431b76cec2c41674de5607 -2026-07-28-remove-synthetic-log-only-turns.zh.md: 3dbcd0d9b258f4ea9f4515ba009e75487a96c342 +2026-07-28-remove-synthetic-log-only-turns.md: 073ac0888054c907087dd0c5f2d01b03a5e87455 +2026-07-28-remove-synthetic-log-only-turns.zh.md: 67b24c7423ee37c40361cb937fdad42243362dfd diff --git a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md index b35045d036..073ac08880 100644 --- a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md +++ b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md @@ -20,7 +20,7 @@ Core session invariants continue to enforce core-owned execution relations: turn The title service appends `session/title` directly after its existing service, revision, cancellation, and live-session checks. The bundled model helper appends its literal `session/title-llm-request` record before dispatch. Persistence admits both through the bounded `session/event` path and drains them at ordinary checkpoints and lifecycle teardown; neither append forces a flush merely because it is between turns. A fallback, auxiliary request record, or accepted provider title may therefore appear after `turn/end` and before the next `turn/start`. Manual compaction uses the same between-turn capability for a `compaction/* { turn: null }` bracket, but explicitly flushes the closed attempt because `/compact` promises durability before releasing queued prompt admission. -`SessionStore.fork()` may end at any stable event position outside an open turn, not only at `turn/end`. This preserves standalone title and other plugin-owned log-only records in a default store fork while still rejecting a prefix cut through active execution. The [Session Controller fork decision](../bug-fix/2026-09-11-session-controller-fork-turn-cut.md) limits its completed-turn operation to the selected closing event. +`SessionStore.fork()` preserves standalone title and other plugin-owned log-only records. The [exact-event fork decision](../feature/2026-08-18-arbitrary-seq-session-fork.md) owns cut selection and child-owned closers for an open tail. The historical [universal turn-enclosure decision](../../archived/architecture/2026-06-15-turn-enclosure-invariant.md) remains useful only as the reason the synthetic mechanism was introduced. The [context-injection decision](../architecture/2026-07-24-separate-context-injection-from-turn-execution.md) established the current meaning: one turn represents one model-loop execution. The [queued manual compaction decision](../feature/2026-07-30-queued-manual-compaction.md) applies that rule to a durable multi-event bracket and owns its marker and admission semantics. @@ -36,7 +36,7 @@ The historical [universal turn-enclosure decision](../../archived/architecture/2 ## Verification -Core invariant tests accept an unknown plugin event between turns while continuing to reject built-in execution events there. Hook, plan-mode, PTC mode dispatch, and approval invariant companions reject their execution-scoped events when no turn is open; the compaction companion separately accepts a balanced `turn: null` manual bracket between turns and requires numeric owners to match an open turn. Session-title service tests pin one direct fallback event under concurrent refresh, detached-session rejection, and newest-revision acceptance. A JSONL round trip preserves a title appended after `turn/end` through the persistence lifecycle drain, and fork tests retain a standalone log-only tail while rejecting boundaries inside an open turn. A keyless assembled ACP snapshot delays the model-backed title until after `turn/end` and pins one standalone provider title with no synthetic turn. Generated API and type-equivalence catalogs contain no removed symbol. +Core invariant tests accept an unknown plugin event between turns while continuing to reject built-in execution events there. Hook, plan-mode, PTC mode dispatch, and approval invariant companions reject their execution-scoped events when no turn is open; the compaction companion separately accepts a balanced `turn: null` manual bracket between turns and requires numeric owners to match an open turn. Session-title service tests pin one direct fallback event under concurrent refresh, detached-session rejection, and newest-revision acceptance. A JSONL round trip preserves a title appended after `turn/end` through the persistence lifecycle drain, and fork tests retain a standalone log-only tail. A keyless assembled ACP snapshot delays the model-backed title until after `turn/end` and pins one standalone provider title with no synthetic turn. Generated API and type-equivalence catalogs contain no removed symbol. ## Consequences diff --git a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.zh.md b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.zh.md index 3dbcd0d9b2..67b24c7423 100644 --- a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.zh.md +++ b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.zh.md @@ -20,7 +20,7 @@ Status: implemented 标题服务会在完成既有的服务状态、修订、取消和活跃会话检查后,直接追加 `session/title`。随附模型辅助函数会在发起调用前追加其字面量 `session/title-llm-request` 记录。持久化通过有界 `session/event` 路径接纳两者,并在常规检查点与生命周期结束时排空;二者都不会仅因为位于轮次之间就强制刷写。因此,回退标题、辅助请求记录或已接受的提供方标题可以出现在 `turn/end` 之后、下一个 `turn/start` 之前。手动压缩(compaction)利用同一项轮次间能力记录 `compaction/* { turn: null }` 标记对,但会显式刷写已闭合的尝试,因为 `/compact` 承诺在放行排队中的提示词前完成持久化。 -`SessionStore.fork()` 可以结束于开放轮次之外的任意稳定事件位置,而不限于 `turn/end`。这样,默认的 store fork 会保留独立标题和其他插件所属的纯日志记录,同时仍拒绝在活跃执行过程中截断前缀。[Session Controller 分叉决策](../bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md)将其已结束轮次操作限制在选中的结束事件处。 +`SessionStore.fork()` 保留独立标题和其他插件所属的纯日志记录。[精确事件 fork 决策](../feature/2026-08-18-arbitrary-seq-session-fork.zh.md)负责切点选择与开放尾部的子会话自有结束事件。 历史上的[通用轮次封闭决策](../../archived/architecture/2026-06-15-turn-enclosure-invariant.md)如今只适合用于解释为何曾引入合成机制。[上下文注入决策](../architecture/2026-07-24-separate-context-injection-from-turn-execution.zh.md)确立了当前语义:一个轮次表示一次模型循环执行。[排队手动压缩决策](../feature/2026-07-30-queued-manual-compaction.zh.md)将该规则应用于持久多事件标记对,并拥有其标记与接纳语义。 @@ -36,7 +36,7 @@ Status: implemented ## 验证 -核心不变量测试会接受轮次之间的未知插件事件,同时继续拒绝位于该处的内置执行事件。钩子、plan-mode、PTC mode 分发和审批的不变量配套组件会在没有开放轮次时拒绝其执行作用域事件;压缩配套组件则另外接受轮次之间平衡的 `turn: null` 手动标记对,并要求数字 owner匹配一个开放轮次。会话标题服务测试会在并发刷新、拒绝已脱离会话和接受最新修订的场景下,固定一个直接追加的回退事件。JSONL 往返测试会通过持久化生命周期排空保留追加在 `turn/end` 之后的标题;fork 测试会保留独立纯日志尾部,同时拒绝位于开放轮次内的边界。一个无密钥、经完整组装的 ACP(Agent Client Protocol)快照会将模型生成的标题延迟到 `turn/end` 之后,并固定一个不含合成轮次的独立提供方标题。生成的 API 和类型等价性目录不含任何已移除符号。 +核心不变量测试会接受轮次之间的未知插件事件,同时继续拒绝位于该处的内置执行事件。钩子、plan-mode、PTC mode 分发和审批的不变量配套组件会在没有开放轮次时拒绝其执行作用域事件;压缩配套组件则另外接受轮次之间平衡的 `turn: null` 手动标记对,并要求数字 owner匹配一个开放轮次。会话标题服务测试会在并发刷新、拒绝已脱离会话和接受最新修订的场景下,固定一个直接追加的回退事件。JSONL 往返测试会通过持久化生命周期排空保留追加在 `turn/end` 之后的标题;fork 测试会保留独立纯日志尾部。一个无密钥、经完整组装的 ACP(Agent Client Protocol)快照会将模型生成的标题延迟到 `turn/end` 之后,并固定一个不含合成轮次的独立提供方标题。生成的 API 和类型等价性目录不含任何已移除符号。 ## 后果 diff --git a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml index 264c685eb9..e5ab7e62d9 100644 --- a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-07-file-content-scan.md -2026-09-07-file-content-scan.md: bf4f03ee5a7134b11c7cbec322b0a37a3f2a6304 -2026-09-07-file-content-scan.zh.md: 5efb1589b036f80b46752a80103c080952c82396 +2026-09-07-file-content-scan.md: 1ec46e7d685394f5165624f1e7b68622ba9f89d3 +2026-09-07-file-content-scan.zh.md: b4ebd835ca8adaf3a7b7fa09150cd5a2bec9f401 diff --git a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.md b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.md index bf4f03ee5a..1ec46e7d68 100644 --- a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.md +++ b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.md @@ -6,11 +6,11 @@ English | [中文](2026-09-07-file-content-scan.zh.md) ## Problem -Every model dispatch checks complete message content for files, including nested tool results. A request-history CPU profile attributes 23.540 ms of self time to `contentHasFile` and 5.584 ms to its callback. This traversal remains necessary even after [loop-owned freeze evidence](2026-09-06-agent-request-freeze-evidence.md) removes repeated request freezing. The hot LLM source is identical at both sampled master revisions and the measured V3 integration revision; these observations do not establish PR causality. +Every model dispatch checks complete message content for files, including tool-role result content. A request-history CPU profile attributes 23.540 ms of self time to `contentHasFile` and 5.584 ms to its callback. This traversal remains necessary even after [loop-owned freeze evidence](2026-09-06-agent-request-freeze-evidence.md) removes repeated request freezing. The hot LLM source is identical at both sampled master revisions and the measured V3 integration revision; these observations do not establish PR causality. ## Decision -[`contentHasFile`](../../../../packages/llm/llm/src/content.ts) uses direct iteration instead of recursive `Array.some` callbacks. It preserves early exit, nested tool-result traversal, and false results for other block kinds. It stores no identities, validation results, or freeze proofs. Image detection, file projection, and request construction keep their existing behavior. The [request-freeze evidence](2026-09-06-agent-request-freeze-evidence.md) owns the request-history budget. +[`contentHasFile`](../../../../packages/llm/llm/src/content.ts) uses direct iteration instead of recursive `Array.some` callbacks. It preserves early exit, tool-role result traversal, and false results for other block kinds. It stores no identities, validation results, or freeze proofs. Image detection, file projection, and request construction keep their existing behavior. The [request-freeze evidence](2026-09-06-agent-request-freeze-evidence.md) owns the request-history budget. ## Measurement evidence diff --git a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.zh.md b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.zh.md index 5efb1589b0..b4ebd835ca 100644 --- a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.zh.md +++ b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.zh.md @@ -6,11 +6,11 @@ Status: implemented ## Problem -每次模型分发都检查完整消息内容中的文件,包括嵌套工具结果。请求历史 CPU profile 将 23.540 ms 自身时间归于 `contentHasFile`,将 5.584 ms 归于其回调。即使[循环自有冻结证据](2026-09-06-agent-request-freeze-evidence.zh.md)消除了重复请求冻结,这次遍历仍然必需。两次抽样的 master 修订与实测的 V3 集成修订 的 LLM 热点源码完全相同;这些观察不能证明 PR 因果关系。 +每次模型分发都检查完整消息内容中的文件,包括 tool-role 结果内容。请求历史 CPU profile 将 23.540 ms 自身时间归于 `contentHasFile`,将 5.584 ms 归于其回调。即使[循环自有冻结证据](2026-09-06-agent-request-freeze-evidence.zh.md)消除了重复请求冻结,这次遍历仍然必需。两次抽样的 master 修订与实测的 V3 集成修订 的 LLM 热点源码完全相同;这些观察不能证明 PR 因果关系。 ## Decision -[`contentHasFile`](../../../../packages/llm/llm/src/content.ts) 使用直接迭代,替代递归的 `Array.some` 回调。它保留提前退出、嵌套工具结果遍历,以及其他块类型返回 false 的行为。它不存储身份、校验结果或冻结证明。图片检测、文件投影和请求构建保持既有行为。[请求冻结证据](2026-09-06-agent-request-freeze-evidence.zh.md)拥有请求历史预算。 +[`contentHasFile`](../../../../packages/llm/llm/src/content.ts) 使用直接迭代,替代递归的 `Array.some` 回调。它保留提前退出、tool-role 结果遍历,以及其他块类型返回 false 的行为。它不存储身份、校验结果或冻结证明。图片检测、文件投影和请求构建保持既有行为。[请求冻结证据](2026-09-06-agent-request-freeze-evidence.zh.md)拥有请求历史预算。 ## Measurement evidence diff --git a/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml new file mode 100644 index 0000000000..d589324465 --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.md +2026-09-08-web-subagent-catalog-projections.md: 766d33e581bcac53844b0836f23cda615858fc27 +2026-09-08-web-subagent-catalog-projections.zh.md: ef14db2530ed10a7aa34408c5a6fada6f0a28858 diff --git a/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.md b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.md new file mode 100644 index 0000000000..766d33e581 --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.md @@ -0,0 +1,31 @@ +# Agent Note: Web subagent catalogs consume shared projections + +Status: implemented + +English | [中文](2026-09-08-web-subagent-catalog-projections.zh.md) + +## Problem + +The parent catalog projection already publishes complete membership through the Session control stream. A separate catalog-change event, repeated RPC reads, and a second membership cache duplicate that delivery and require coordination between responses and later events. Historical Sessions still need initial loading when their projection is absent, and parent Agent availability remains independent of durable membership. + +## Decision + +The Client retains catalog membership only in its standard per-Session projection store. Initial `session.projections` reads return a complete projection baseline from one live-preferred Session observation. The endpoint accepts any Session id and has no catalog-specific dependency or validation. The same observation supplies the values and sequence cursor. Initial baselines and live control frames use the store's existing sequence ordering, so an older response cannot replace a newer value. The endpoint does not activate an Agent or sample child activity. Opening a conversation uses its follow baseline without scheduling a second projection read; unopened catalog branches still use explicit reads. + +Feature consumers select `subagentCatalog` from `projectionsBySession` and derive row activity from Session-list baselines and status events. Session summaries report Agent availability separately; Agent creation and disposal republish the existing summary event. Completed subagents retain their summaries and display projections after removal. Generic projection reads own loading and error state; parent availability comes from the Session list independently of membership. Opening a loaded catalog reuses its data; an initial failure can be retried. Reconnect cancels previous reads and starts fresh reads for requested catalogs. Session removal cancels its pending read and marks parent availability false; projection responses cannot change Agent availability. + +The [parent-catalog decision](../architecture/2026-09-01-parent-owned-subagent-catalog.md) owns durable creation facts and ordering. This decision supersedes the dedicated membership-refresh mechanism in [Web subagent conversations](../feature/2026-07-27-web-subagent-conversations.md); that note remains active for navigation, control, and presentation decisions. + +Host summaries replace running and availability state; local create/fork placeholders only enrich missing metadata. Sharing overwrite behavior would let a late local response erase a newer Host state and generate a false completion reminder. Removed ordinary Sessions retain stores only for nonempty child catalogs; empty catalogs carry no navigation that needs to survive removal. Breadcrumb selectors derive addresses from the Session-list snapshot so their subscriptions cover every dependency. + +## Alternatives considered + +**Keep notification-driven reads.** Rejected because the shared stream already delivers the changed value. Menu subscriptions, response-local activity replay, and trailing membership reads add no required delivery capability. + +**Remove the initial-read endpoint.** Deferred. Session-list projections are cache hints and may be absent; following a conversation also transfers history and retains observation state. A lightweight read preserves historical catalog access without establishing a conversation follow stream. Parent availability is a live delivery hint, not a durable projection fact. + +## Consequences + +Membership changes use the existing control stream without extra catalog notifications or reads. Whole-value projection publication still costs O(D) for D children; this change does not introduce delta transport. Initial reads return the observation's complete projection baseline, including values beyond the catalog, so they reuse standard baseline semantics at the cost of that additional initial payload. Session sequence ordering does not establish identity across reused Session ids. + +Manager tests cover pushed membership, stale initial responses, lazy loading, status composition, retained completion metadata, retry, removal of empty catalogs, late create/fork responses, and reconnect cancellation. Host tests exercise the shared control stream and cold observations. The persisted-subagent Web scenario covers nested historical navigation and continuation through the shipped application. diff --git a/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.zh.md b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.zh.md new file mode 100644 index 0000000000..ef14db2530 --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.zh.md @@ -0,0 +1,31 @@ +# Agent Note:Web 子代理目录消费共享 projection + +Status: implemented + +[English](2026-09-08-web-subagent-catalog-projections.md) | 中文 + +## 问题 + +父目录 projection 已通过 Session control stream 发布完整成员关系。独立的目录变化事件、重复 RPC 读取与第二份成员缓存重复传递同一数据,并要求协调响应与后续事件。历史 Session 的 projection 缺席时仍需初始加载,父 Agent 可用性也独立于持久成员关系。 + +## 决策 + +Client 仅在标准逐 Session projection store 中保留目录成员关系。初始 `session.projections` 读取通过一次 live-preferred Session observation 返回完整 projection 基线。endpoint 接受任意 Session id,不含目录专用依赖或校验。值与序号游标来自同一次 observation。初始基线与实时 control 帧使用 store 既有的序号排序,因此旧响应不能替换新值。该 endpoint 不激活 Agent,也不采样子代理活动状态。打开会话时使用其 follow baseline,不再额外调度一次投影读取;未打开的目录分支仍使用显式读取。 + +功能消费者从 `projectionsBySession` 中选择 `subagentCatalog`,并从 Session 列表基线与状态事件派生行活动状态。Session 摘要单独报告 Agent 可用性;Agent 创建与销毁重新发布已有摘要事件。完成的子代理在移除后保留摘要与展示 projection。通用 projection 读取拥有加载与错误状态;父 Agent 可用性来自 Session 列表,独立于成员关系。打开已加载目录会复用数据,初始失败可以重试。重连取消此前的读取,并为已请求的目录重新读取。Session 移除会取消其待完成读取并将父 Agent 可用性标为 false;projection 响应不能改变 Agent 可用性。 + +[父目录决策](../architecture/2026-09-01-parent-owned-subagent-catalog.zh.md) 说明持久创建事实与顺序。本决策取代 [Web 子代理会话](../feature/2026-07-27-web-subagent-conversations.zh.md) 中的专用成员刷新机制;该记录继续保留导航、控制与展示决策。 + +Host 摘要替换运行状态与可用性;本地 create/fork 占位摘要只补充缺失的元数据。若共用覆盖行为,晚到的本地响应会抹去较新的 Host 状态,并生成虚假的完成提醒。普通 Session 移除后,仅为非空子目录保留 store;空目录没有需要保留的导航关系。面包屑 selector 从 Session 列表快照推导地址,使订阅涵盖全部依赖。 + +## 考虑过的替代方案 + +**保留通知驱动的读取。** 不采用,因为共享流已经传递变化后的值。菜单订阅、请求内活动状态回放与尾随成员读取没有提供额外的必要传递能力。 + +**删除初始读取 endpoint。** 暂缓。Session 列表 projection 是可能缺席的缓存提示;跟随会话还会传输历史并保留 observation 状态。轻量读取保留历史目录访问能力,无需建立会话跟随流。父 Agent 可用性是实时投递提示,而非持久 projection 事实。 + +## 影响 + +成员变化使用既有 control stream,无需额外目录通知或读取。对 D 个子级发布完整 projection 值仍需 O(D);本变更不引入增量传输。初始读取返回 observation 的完整 projection 基线,其中包括目录以外的值,以额外初始载荷换取标准基线语义的复用。Session 序号排序不确立复用 Session id 之间的身份关系。 + +Manager 测试覆盖成员推送、过时初始响应、按需加载、状态组合、完成元数据保留、重试、空目录移除、晚到的 create/fork 响应与重连取消。Host 测试覆盖共享 control stream 与冷 observation。持久化子代理 Web 场景通过发布应用验证嵌套历史导航与续传。 diff --git a/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml new file mode 100644 index 0000000000..a6c46b0bbd --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.md +2026-09-16-subagent-catalog-membership-only.md: d1d0956380ef2b2ffd610e5a3d07c7988991e42e +2026-09-16-subagent-catalog-membership-only.zh.md: 4225a331a0b3c483349760cd805416a94c4b915a diff --git a/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.md b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.md new file mode 100644 index 0000000000..d1d0956380 --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.md @@ -0,0 +1,25 @@ +# Agent Note: Keep model configuration outside subagent catalogs + +Status: implemented + +English | [中文](2026-09-16-subagent-catalog-membership-only.zh.md) + +## Problem + +The parent catalog serves direct-child discovery. Recording a child's creation-time LLM provider and model would preserve immutable configuration without opening child histories, but discovery and navigation consumers do not read those values. Creation configuration also does not establish which model served a request. + +## Decision + +The catalog event and projection retain child identity, creation time, mode, and label. `establishCatalogChild(parent, childHeader, descriptor)` receives only the values needed to publish membership. Child composition and request history retain their own model configuration; catalog loading adds no child observation or model lookup. + +This decision supersedes only the creation-model metadata choice in the [parent-catalog decision](../architecture/2026-09-01-parent-owned-subagent-catalog.md). That note remains active for successful publication, event order, fork isolation, and projection ownership. The unreleased optional metadata declaration and its dedicated expectations are absent; existing historical Session generations from the migration base remain intact. + +## Alternatives considered + +**Keep optional creation metadata for future display.** Optional fields still require durable schemas, cache invalidation, producers, and replay expectations. A consumer requiring the immutable creation route could justify those costs; current consumers do not require it. + +**Read child histories during discovery.** This adds work proportional to child histories without helping membership. A display that needs the model used by a request can observe the child's existing `modelSelection` projection independently. + +## Consequences + +The catalog provides no historical creation-route record. Reintroducing one requires a consumer whose requirement cannot be met by the existing child composition or request projections. Initial reads, live updates, reconnect, and authorization keep their existing owners. Catalog and creation tests, recorded-session replay, and both SDK expectations verify that membership still publishes without the extra metadata. diff --git a/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.zh.md b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.zh.md new file mode 100644 index 0000000000..4225a331a0 --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.zh.md @@ -0,0 +1,25 @@ +# Agent Note: 将模型配置保留在子代理目录之外 + +Status: implemented + +[English](2026-09-16-subagent-catalog-membership-only.md) | 中文 + +## 问题 + +父目录用于发现直接子级。记录子级创建时的 LLM provider 和 model,可以在不打开子级历史的情况下保留不可变配置,但发现与导航的消费者不读取这些值。创建配置也不能确定实际处理某次请求的模型。 + +## 决策 + +目录事件与投影保留子级身份、创建时间、模式和标签。`establishCatalogChild(parent, childHeader, descriptor)` 只接收发布成员关系所需的值。子级组合与请求历史各自保留模型配置;目录加载不增加子级观察或模型查询。 + +本决策仅替代[父目录决策](../architecture/2026-09-01-parent-owned-subagent-catalog.zh.md)中的创建模型元数据选择。该记录继续说明成功发布、事件顺序、fork 隔离和投影所有权。未发布的可选元数据声明及其专属预期输出不予保留;迁移基线中已有的历史 Session 世代保持完整。 + +## 考虑过的替代方案 + +**保留可选创建元数据,供未来展示使用。** 可选字段仍需要持久化 schema、缓存失效、写入方和回放预期输出。需要不可变创建路由的消费者可以证明这些成本合理,但当前消费者没有此需求。 + +**在发现过程中读取子级历史。** 这会增加与子级历史规模相关的工作,却不帮助确定成员关系。需要展示请求实际使用模型的功能,可以独立观察子级已有的 `modelSelection` 投影。 + +## 后果 + +目录不提供历史创建路由记录。重新引入此记录,需要存在无法通过已有子级组合或请求投影满足需求的消费者。初始读取、实时更新、重连和授权继续由现有模块负责。目录与创建测试、已记录 Session 回放以及两套 SDK 的预期输出验证了成员关系仍可在没有额外元数据的情况下发布。 diff --git a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml index f25fc6d416..2eb9f0f8ea 100644 --- a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.md -2026-09-04-session-open-performance-gate.md: eaf7c6045bca12329d81cf9c968fb191229b0add -2026-09-04-session-open-performance-gate.zh.md: e9bf13460aafbd962a1d15b7a7d240f0b4be6b4e +2026-09-04-session-open-performance-gate.md: 1b2b0aabb79aceb0ac515a1d90ba3e2ba042535c +2026-09-04-session-open-performance-gate.zh.md: 9ad56796aac6310977aedfff0f9188e46cbbf3d7 diff --git a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.md b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.md index eaf7c6045b..1b2b0aabb7 100644 --- a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.md +++ b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.md @@ -78,6 +78,22 @@ The calibrated source budgets are: | Client-fold delta scaling | 2.5× | 3.125× | | Constrained old space | — | 128 MB | +### Indexed traversal of stored JSON arrays + +The JSONL backend freezes decoded event graphs before memoization. Its native decoder and fixed migration catalog produce acyclic JSON graphs whose arrays contain only indexed values. Numeric array traversal preserves freezing of every nested object and array while avoiding string-key enumeration across the compact stream's 125,000 text entries and 124,600 time deltas. Object traversal still preserves own `__proto__` and `constructor` data. No admission, relationship validation, decoding, or freezing moves beyond the measured open endpoint, and a shallow `Object.isFrozen()` result never skips descendant traversal. + +On an Apple M4 Pro with Node 24.19.0, an open-only CPU profile attributes about 4.2 ms to complete event freezing. Separate fresh-process V4 runs give these results; the final column restores and rebuilds the exact original traversal as a negative control: + +| Reopen measurement | Original traversal | Indexed traversal | Original restored | +|---|---|---|---| +| `open` samples (ms) | 22.2, 22.4, 22.8, 22.6, 22.9 | 17.7, 18.4, 17.4, 17.8, 17.6 | 21.7, 22.4, 22.2, 21.7, 21.6 | +| Median `open` (ms) | 22.6 | 17.7 | 21.7 | +| Median first history (ms) | 35.0 | 30.6 | 33.6 | +| Median Agent resume (ms) | 30.5 | 26.8 | 29.8 | +| Agent retained heap (MB) | 4.5 | 4.5 | 4.5 | + +Each run passes all 17 Session cases, including the 128 MB completion checks. The original implementation remains below 63 ms on this local machine; the restored traversal demonstrates the removed cost, while the hosted benchmark remains the required budget verdict. The workload, time limits, memory limits, cold-process setup, and measurement endpoints are unchanged. The JSONL owner tests cover nested opaque JSON, rejected mutation, and immutable event sharing through historical V3 and current reads. These measurements establish a reopen improvement; they do not establish a consistent first-open improvement or hosted-runner timing. + ## Alternatives considered **Check out the historical commit and compare it on every CI run.** Rejected because a historical checkout requires a separate install, and old and current revisions can assign work to different API phases, adding runtime, dependency, and interface drift. A fixed workload with static budgets calibrated against positive and negative controls is easier to reproduce and review. diff --git a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.zh.md b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.zh.md index e9bf13460a..9ad56796aa 100644 --- a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.zh.md +++ b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.zh.md @@ -78,6 +78,22 @@ PR #3640 的标准双 CPU 运行 (run 34023970384, job 101461539961)使用 Node | Client fold delta 缩放比 | 2.5× | 3.125× | | 受限 old space | — | 128 MB | +### 按索引遍历持久化 JSON 数组 + +JSONL backend 在 memo 化前冻结解码后的 event graph。原生 decoder 与固定 migration catalog 产出无环 JSON graph,其中数组只包含索引值。按数字索引遍历数组仍会冻结每个嵌套对象和数组,同时避免枚举 compact stream 中 125,000 个文本条目和 124,600 个时间差值的字符串键。对象遍历继续保留自有的 `__proto__` 和 `constructor` 数据。Admission、关系校验、解码与冻结都仍在被测 open 终点前完成;浅层 `Object.isFrozen()` 结果不会跳过后代遍历。 + +在 Apple M4 Pro、Node 24.19.0 上,仅覆盖 open 的 CPU profile 将约 4.2 ms 归因于完整 event 冻结。独立的全新进程 V4 运行得到以下结果;末列恢复并重新构建完全相同的原始遍历,作为负对照: + +| Reopen 测量项 | 原始遍历 | 索引遍历 | 恢复原始遍历 | +|---|---|---|---| +| `open` 样本(ms) | 22.2, 22.4, 22.8, 22.6, 22.9 | 17.7, 18.4, 17.4, 17.8, 17.6 | 21.7, 22.4, 22.2, 21.7, 21.6 | +| `open` 中位数(ms) | 22.6 | 17.7 | 21.7 | +| 首屏历史中位数(ms) | 35.0 | 30.6 | 33.6 | +| Agent resume 中位数(ms) | 30.5 | 26.8 | 29.8 | +| Agent 保留堆(MB) | 4.5 | 4.5 | 4.5 | + +每次运行的全部 17 个 Session 用例均通过,包括 128 MB 完成性检查。原始实现在本机仍低于 63 ms;恢复原始遍历展示了被移除的成本,而托管 benchmark 仍负责给出必须满足的预算结果。工作负载、时间上限、内存上限、冷进程准备与测量终点保持不变。JSONL owner 测试覆盖历史 V3 和当前读取中的嵌套不透明 JSON、修改拒绝及不可变 event 共享。这些测量确认了 reopen 改善,但没有确认一致的 first-open 改善或托管运行器耗时。 + ## 考虑过的替代方案 **每次 CI checkout 历史提交并做相对比较。** 拒绝:历史 checkout 需要独立安装,旧版与当前版还可能把工作放在不同 API 阶段,增加时间、依赖和接口漂移。固定 workload 与经正反例校准的静态预算更容易复现和评审。 diff --git a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml index f63c4924fd..aeaed20365 100644 --- a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md -2026-09-06-backend-continuation-performance.md: a30c7a47a93f0a8827d1cb4d0857aeabe9dd2fee -2026-09-06-backend-continuation-performance.zh.md: c703ea70e496d279e5965295d308a2919ed2b445 +2026-09-06-backend-continuation-performance.md: a2423a404e23f6a4ccb6a4fb177ec6842b7bf584 +2026-09-06-backend-continuation-performance.zh.md: 942cfd37528d121bf482c48c5d75dd1f2de30887 diff --git a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md index a30c7a47a9..a2423a404e 100644 --- a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md +++ b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md @@ -19,13 +19,13 @@ The shared history has 800 completed two-step turns, four tool calls per turn, a | Request history | After unmeasured cold resume, deliver 40 sequential text-only turns over the tool-heavy history, then flush | Idle Agent with all 40 model requests completed; reports turn and final-flush time separately | | Tool continuation | Cold resume, 20 sequential turns with eight parallel-safe synthetic tool calls and a final reply per turn, then flush | Idle Agent with 40 model requests and 160 completed tool executions; reports resume, turns, and final flush separately | | Shipped SDK workflow | Launch built dsh with the sdk-minimal profile, deliver 100 sequential turns with eight real file-view calls per turn, then close the SDK | SDK receives 200 assistant messages and 800 successful file results; includes Loader boot, stdio JSON-RPC, persistence, and shutdown | -| Child catalog | List 16 inactive seeded fork children twice through the real subagent and Session query services | Two complete healthy catalogs with observations released; each child inherits 80 tool-heavy turns and owns its descriptor after the exact fork cut | +| Child catalog | Observe one cold parent catalog twice through the real Session query and subagent services | Two complete 16-child catalogs with parent observations released; each stored fork child inherits 80 tool-heavy turns, and discovery reads only the parent facts | The tool execution pipeline, request preparation, Session projections required by those services, persistence, and catalog observations remain production code. Only the model adapter and bounded tool body are synthetic. The adapter retains a request counter, not request objects, so the fixture cannot manufacture a growing retention cost. Sequential input means each idle interval belongs to the one request delivered by this worker; it does not generalize idle to a per-message completion API under concurrent input. The SDK fixture explicitly inserts `fs-local` and `str_replace_editor` through its profile patch. This preserves the calibrated file-view workload independently of the [minimal profile's shell-only defaults](../simplification/2026-09-03-minimal-profiles-persistent-shell-only.md). File reads, timing endpoints, and budgets remain the same. -Five samples report raw wall time, CPU user/system time, peak RSS, endpoint counts, and the minimum, median, and maximum total wall time. Each aggregate report also records CPU models, available parallelism, platform, architecture, and Node/V8 versions after the timed workers exit. Budgets enforce the unrounded median. Continuation additionally measures retained heap against an initialized Host: two explicit GCs separated by an event-loop yield precede and follow the timed operation, while the idle Agent remains reachable. The measured delta therefore includes the resident historical Session and live additions, not just newly appended turns. GC and teardown are outside timing; flush is inside. Request-history retention starts after resume and is diagnostic only. Catalog peak RSS is diagnostic; no retained-heap budget claims to measure already-released child observations. +Five samples report raw wall time, CPU user/system time, peak RSS, endpoint counts, and the minimum, median, and maximum total wall time. Each aggregate report also records CPU models, available parallelism, platform, architecture, and Node/V8 versions after the timed workers exit. Budgets enforce the unrounded median. Continuation additionally measures retained heap against an initialized Host: two explicit GCs separated by an event-loop yield precede and follow the timed operation, while the idle Agent remains reachable. The measured delta therefore includes the resident historical Session and live additions, not just newly appended turns. GC and teardown are outside timing; flush is inside. Request-history retention starts after resume and is diagnostic only. Catalog peak RSS is diagnostic; no retained-heap budget claims to measure already-released parent observations. The parent bounds every child to 60 seconds, checks timeout, signal, exit, and report independently, awaits process close, and removes private roots after failures. Context and Agent teardown run in finally blocks. Seed processes cannot warm the measured process's caches. Filesystem caches are not forcibly evicted: cold means a fresh process, not cold physical storage. @@ -41,7 +41,7 @@ The implementation reference is the PR #3537 merge on Apple M4 Pro, macOS arm64, Continuation retains approximately 22.295 MiB; its source expectation is 23 MiB and its budget is 28.75 MiB. SDK time expectations use the existing [calibration helper](../../../../benchmarks/support/calibration.ts): 2× shared CI time scale and 1.25× variance headroom. Request history uses the direct hosted expectation in the [request-freeze calibration](../simplification/2026-09-06-agent-request-freeze-evidence.md), without the 2× scale. Memory uses only 1.25× headroom. The scale is inherited from the existing lane's calibration, not a new Linux measurement of these cases; CI evidence remains necessary when runner characteristics change. Baseline budgets protect the measured implementation; tighter budgets belong with a measured behavior-preserving fix. -A separate plain-Node request-history CPU profile attributes 132.876 ms of sampled self time to deepFreeze called by buildRequest during a 211.300 ms operation. This identifies repeated traversal of already-frozen history as a focused investigation target, not a proven optimization result. Catalog first/repeat timings remain separate because a second listing still reads body-bearing seeded children after observations are released. +A separate plain-Node request-history CPU profile attributes 132.876 ms of sampled self time to deepFreeze called by buildRequest during a 211.300 ms operation. This identifies repeated traversal of already-frozen history as a focused investigation target, not a proven optimization result. Catalog first/repeat timings separately report the first and second parent-catalog observations. The shipped SDK variant completes 100 turns, 200 requests, and 800 real file reads. Its five-sample smoke totals are 1,521.773, 1,463.465, 1,689.701, 1,365.485, and 1,417.106 ms (median 1,463.465 ms); a full-suite repeat reports 1,596.183, 1,784.536, 2,120.082, 1,405.365, and 1,355.894 ms (median 1,596.183 ms). Its 1,700 ms reference expectation yields a 4,250 ms CI budget. The repeat also slows the unchanged service cases, so it is validation under variable host load rather than evidence to relax their exclusive calibration. The SDK process receives an allowlisted environment and private home/workspace. A 40-second deadline starts SDK shutdown; every path awaits the same memoized close promise before the outer worker’s 60-second deadline. Profile timing includes boot, all turns, and shutdown, reported separately; no parent-process CPU or heap metric is presented as server memory. The adapter does not serialize requests for an external model provider. @@ -59,7 +59,7 @@ Baseline request history uses a 600 ms expected CI duration with 1.25× headroom **Measure only deriveMessages.** Rejected: its incremental cache does not include complete request freezing, adapter dispatch, live append, or persistence. Actual sequential requests protect the cost the Agent pays per step. -**Use only unseeded children with warm projection-cache rows.** Rejected: that path bypasses body observations and misses the exact inherited-cut requirement of fork children. The catalog intentionally omits the optional projection cache and reports the seeded fallback path; it does not characterize cache-hit discovery. +**Use only unseeded children with warm projection-cache rows.** Rejected: that path bypasses body observations and misses the exact inherited-cut requirement of fork children. The original calibration omits the optional projection cache and reports the seeded fallback path. Current catalog reads observe durable parent facts; the recorded child-body timings describe the calibration implementation. **Apply an optimization and its desired budget together with the first measurements.** Rejected: a baseline-only layer remains independently mergeable and records the current workload before attribution or implementation changes. Source constants cannot be overridden by environment variables. diff --git a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.zh.md b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.zh.md index c703ea70e4..942cfd3752 100644 --- a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.zh.md +++ b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.zh.md @@ -19,13 +19,13 @@ Status: implemented | 请求历史 | 在不计时的冷恢复后,向工具密集历史顺序提交 40 个纯文本轮次,然后 flush | 空闲 Agent,已完成全部 40 次模型请求;分别报告轮次和最终 flush 时间 | | 工具续聊 | 冷恢复,顺序执行 20 个轮次,每轮八次可安全并行的合成工具调用和一条最终回复,然后 flush | 空闲 Agent,已完成 40 次模型请求和 160 次工具执行;分别报告恢复、轮次和最终 flush 时间 | | 已发布 SDK 工作流 | 使用 sdk-minimal profile 启动已构建 dsh,顺序提交 100 个轮次,每轮八次真实文件查看调用,然后关闭 SDK | SDK 收到 200 条助手消息和 800 个成功文件结果;包含 Loader 启动、stdio JSON-RPC、持久化和关闭 | -| 子会话目录 | 通过真实 subagent 和 Session 查询服务,两次列出 16 个非活动、带种子的 fork 子会话 | 两份完整健康目录,观察已释放;每个子会话继承 80 个工具密集轮次,并在精确 fork 切点后拥有自己的描述符 | +| 子会话目录 | 通过真实 Session 查询和 subagent 服务,两次观察一个冷 parent 目录 | 两份完整的 16 子级目录,parent 观察已释放;每个存储的 fork 子级继承 80 个工具密集轮次,发现只读取 parent fact | 工具执行管线、请求准备、这些服务所需的 Session 投影、持久化和目录观察均保留生产代码。只有模型适配器和有界工具体是合成的。适配器只保留请求计数,不保留请求对象,因此 fixture(测试前置数据)不会制造不断增长的保留成本。顺序输入使每个空闲区间对应此 worker 提交的唯一请求;这不代表并发输入时可以把空闲状态推广为逐消息完成 API。 SDK fixture 通过 profile patch 显式插入 `fs-local` 和 `str_replace_editor`。这使经校准的文件查看负载不依赖[极简 profile 只提供 shell 的默认组合](../simplification/2026-09-03-minimal-profiles-persistent-shell-only.zh.md)。文件读取、计时终点和预算保持不变。 -五个样本报告原始壁钟时间、CPU 用户态/内核态时间、峰值 RSS、终点计数及总壁钟时间的最小值、中位数和最大值。每份汇总报告还在计时 worker 退出后记录 CPU 型号、可用并行度、平台、架构以及 Node/V8 版本。预算约束未经舍入的中位数。续聊还相对已初始化 Host 测量保留堆内存:计时操作前后各执行两次显式 GC,中间让出一次事件循环,空闲 Agent 始终可达。因此该增量包含常驻历史 Session 和实时追加,而不只是新轮次。GC 与资源释放不计时;flush 计时。请求历史的内存基线从恢复后开始,只作诊断。目录峰值 RSS 仅作诊断;没有保留堆预算声称衡量已经释放的子会话观察。 +五个样本报告原始壁钟时间、CPU 用户态/内核态时间、峰值 RSS、终点计数及总壁钟时间的最小值、中位数和最大值。每份汇总报告还在计时 worker 退出后记录 CPU 型号、可用并行度、平台、架构以及 Node/V8 版本。预算约束未经舍入的中位数。续聊还相对已初始化 Host 测量保留堆内存:计时操作前后各执行两次显式 GC,中间让出一次事件循环,空闲 Agent 始终可达。因此该增量包含常驻历史 Session 和实时追加,而不只是新轮次。GC 与资源释放不计时;flush 计时。请求历史的内存基线从恢复后开始,只作诊断。目录峰值 RSS 仅作诊断;没有保留堆预算声称衡量已经释放的父会话观察。 父进程为每个子进程设置 60 秒上限,独立检查超时、信号、退出状态和报告,等待进程关闭,并在失败后删除私有根目录。Context 和 Agent 在 finally 中释放。播种进程无法预热被测进程的缓存。不强制清除文件系统缓存:冷指新进程,不指冷物理存储。 @@ -41,7 +41,7 @@ SDK fixture 通过 profile patch 显式插入 `fs-local` 和 `str_replace_editor 续聊保留约 22.295 MiB;源码期望值为 23 MiB,预算为 28.75 MiB。SDK 时间期望值使用现有[校准辅助函数](../../../../benchmarks/support/calibration.ts):2× 共享 CI 时间比例和 1.25× 波动余量。请求历史使用[请求冻结校准](../simplification/2026-09-06-agent-request-freeze-evidence.zh.md)中的直接托管期望值,不乘以 2× 比例。内存只使用 1.25× 余量。比例继承现有通道的校准,并非这些用例的新 Linux 实测值;runner 特征变化时仍需 CI 证据。基线预算保护实测实现;更紧预算属于有测量依据且保持行为的修复。 -独立的纯 Node 请求历史 CPU profile 在一次 211.300 ms 操作中,将 132.876 ms 采样自身时间归因于 buildRequest 调用的 deepFreeze。这把重复遍历已冻结历史定位为聚焦调查目标,不是已证实的优化结果。目录首次/重复时间分别保留,因为观察释放后第二次列举仍读取带种子子会话的正文。 +独立的纯 Node 请求历史 CPU profile 在一次 211.300 ms 操作中,将 132.876 ms 采样自身时间归因于 buildRequest 调用的 deepFreeze。这把重复遍历已冻结历史定位为聚焦调查目标,不是已证实的优化结果。目录首次/重复时间分别报告第一次和第二次 parent 目录观察。 已发布 SDK 变体完成 100 个轮次、200 次请求和 800 次真实文件读取。五样本 smoke 总时间为 1,521.773、1,463.465、1,689.701、1,365.485 和 1,417.106 ms(中位数 1,463.465 ms);完整套件重复运行报告 1,596.183、1,784.536、2,120.082、1,405.365 和 1,355.894 ms(中位数 1,596.183 ms)。1,700 ms 参考期望对应 4,250 ms CI 预算。重复运行中未改变的服务用例也变慢,因此这是可变主机负载下的验证,不是放宽其独占校准预算的依据。SDK 进程使用白名单环境和私有主目录/工作区。40 秒截止时间启动 SDK 关闭;所有路径等待同一个记忆化 close Promise,并早于外层 worker 的 60 秒截止时间。Profile 时间包含启动、全部轮次和关闭,分别报告;不把父进程 CPU 或堆指标当作服务端内存。适配器不为外部模型服务商序列化请求。 @@ -59,7 +59,7 @@ SDK fixture 通过 profile patch 显式插入 `fs-local` 和 `str_replace_editor **只测 deriveMessages。** 拒绝:它的增量缓存不包含完整请求冻结、适配器分发、实时追加或持久化。实际顺序请求保护 Agent 每一步支付的成本。 -**只使用投影缓存行已预热的无种子子会话。** 拒绝:该路径绕过正文观察,遗漏 fork 子会话的精确继承切点要求。目录用例有意不挂载可选投影缓存,报告带种子的回退路径;它不代表缓存命中的发现过程。 +**只使用投影缓存行已预热的无种子子会话。** 拒绝:该路径绕过正文观察,遗漏 fork 子会话的精确继承切点要求。原始校准有意不挂载可选投影缓存,报告带种子的回退路径。parent 自有目录的测量观察持久 parent fact;子级正文读取只属于已记录的校准实现。 **将优化及其目标预算与首次测量一起应用。** 拒绝:纯基线层可以独立合并,并在归因或实现改变前记录当前负载。环境变量不能覆盖源码常量。 diff --git a/apps/cli/reference/README.i18n.yaml b/apps/cli/reference/README.i18n.yaml index 7f03e75b67..0cff0e5cdb 100644 --- a/apps/cli/reference/README.i18n.yaml +++ b/apps/cli/reference/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/cli/reference/README.md -README.md: 5bc0b1f12ebce558925ee61bb053bfc1f10d208b -README.zh.md: 602d4440652eb1874cb54817d19a3f00bd83fe0d +README.md: cf0e1400f2dc8cd29cc59cefbdda379df2e0b899 +README.zh.md: a01818f59ccf54f3f826c68505bfb830a9316664 diff --git a/apps/cli/reference/README.md b/apps/cli/reference/README.md index 5bc0b1f12e..cf0e1400f2 100644 --- a/apps/cli/reference/README.md +++ b/apps/cli/reference/README.md @@ -116,4 +116,4 @@ Install external plugin bundles through `dsh plugin --profile add ## Source execution -From the repository root, run `pnpm run build` separately after a fresh checkout and whenever artifacts need updating, then use `pnpm dsh `. The `package.json` script launches `apps/cli/src/bin.ts` with `node --import tsx/esm` without building and forwards every argument. Missing Typert host artifacts fail profile boot through module-resolution errors without a build instruction. Once those host artifacts exist, missing frontend or client-plugin bundles fail at startup with an instruction to run `pnpm run build`. The launcher does not check freshness, so existing stale bundles can run older browser code until rebuilt. The process inherits the launch environment, and `runProfile` resolves the outbound proxy from that snapshot before any entry mounts, so `HTTP_PROXY`/`HTTPS_PROXY` (and a proxy declared in a `.env` layer) apply without any further flag. The installed form launches the built `apps/cli/lib/bin.js` without rebuilding the repository. +From the repository root, run `pnpm run build` separately after a fresh checkout and whenever artifacts need updating, then use `pnpm dsh `. The `package.json` script launches `apps/cli/src/bin.ts` with `node --import tsx/esm` without building and forwards every argument. Missing Typert host artifacts fail profile boot through module-resolution errors without a build instruction. Once those host artifacts exist, missing frontend or client-plugin bundles fail at startup with an instruction to run `pnpm run build`. The launcher does not check freshness, so existing stale bundles can run older browser code until rebuilt. The process inherits the launch environment, and `runProfile` resolves the outbound proxy from that snapshot before any entry mounts, so `HTTP_PROXY`/`HTTPS_PROXY` (and a proxy declared in a `.env` layer) apply without any further flag. The source entry explicitly selects linked profile resolution so tsx workspace imports and profile plugins share module identities. The installed form launches the built `apps/cli/lib/bin.js` with runtime profile resolution without rebuilding the repository. diff --git a/apps/cli/reference/README.zh.md b/apps/cli/reference/README.zh.md index 602d444065..a01818f59c 100644 --- a/apps/cli/reference/README.zh.md +++ b/apps/cli/reference/README.zh.md @@ -118,4 +118,4 @@ dsh web --help ## 源码执行 -请在仓库根目录中,于全新 checkout 之后及产物需要更新时单独运行 `pnpm run build`,然后使用 `pnpm dsh `。`package.json` 中的脚本不会构建,而是通过 `node --import tsx/esm` 启动 `apps/cli/src/bin.ts`,并转发所有参数。Typert Host 产物缺失时,profile 启动会因不含构建指引的模块解析错误而失败。这些 Host 产物存在后,如果前端或 Client plugin 组合包缺失,启动会失败并提示运行 `pnpm run build`。启动器不会检查产物是否为最新,因此已有的陈旧组合包可能继续运行旧版浏览器代码,直至重新构建。该进程会继承启动环境,且 `runProfile` 会在任何 entry 挂载之前从该快照解析出站代理,因此 `HTTP_PROXY`/`HTTPS_PROXY`(以及写在 `.env` 层中的代理)无需任何额外开关即可生效。安装形式会直接启动构建后的 `apps/cli/lib/bin.js`,不会重新构建仓库。 +请在仓库根目录中,于全新 checkout 之后及产物需要更新时单独运行 `pnpm run build`,然后使用 `pnpm dsh `。`package.json` 中的脚本不会构建,而是通过 `node --import tsx/esm` 启动 `apps/cli/src/bin.ts`,并转发所有参数。Typert Host 产物缺失时,profile 启动会因不含构建指引的模块解析错误而失败。这些 Host 产物存在后,如果前端或 Client plugin 组合包缺失,启动会失败并提示运行 `pnpm run build`。启动器不会检查产物是否为最新,因此已有的陈旧组合包可能继续运行旧版浏览器代码,直至重新构建。该进程会继承启动环境,且 `runProfile` 会在任何 entry 挂载之前从该快照解析出站代理,因此 `HTTP_PROXY`/`HTTPS_PROXY`(以及写在 `.env` 层中的代理)无需任何额外开关即可生效。源码入口显式选择链接式 profile 解析,使 tsx workspace 导入与 profile 插件共享模块身份。安装形式会使用 runtime profile 解析直接启动构建后的 `apps/cli/lib/bin.js`,不会重新构建仓库。 diff --git a/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/control-surface-llm.ts b/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/control-surface-llm.ts index b438799e38..347389996f 100644 --- a/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/control-surface-llm.ts +++ b/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/control-surface-llm.ts @@ -43,12 +43,12 @@ class ControlSurfaceAdapter extends LlmAdapter { } override async * stream(options: GenerateOptions): AsyncIterable { - const lastUserIndex = options.messages.findLastIndex(message => message.source.kind === 'user') + const lastUserIndex = options.messages.findLastIndex(message => message.role === 'user' && message.source?.kind === 'user') const current = options.messages.slice(lastUserIndex) const userText = current.flatMap(message => message.content) .flatMap(block => block.type === 'text' ? [block.text] : []) .join('') - const hasToolResult = current.some(message => message.content.some(block => block.type === 'tool-result')) + const hasToolResult = current.some(message => message.role === 'tool') if (!hasToolResult) { const callId = ToolCallId(userText.includes('cancel') ? 'control-cancel-add' : 'control-add') yield { type: 'block-start', index: 0, blockType: 'reasoning' } diff --git a/apps/cli/tests/profiles/acp/tests/goal.expected.e2e.ts b/apps/cli/tests/profiles/acp/tests/goal.expected.e2e.ts index 852e58453c..692438ad87 100644 --- a/apps/cli/tests/profiles/acp/tests/goal.expected.e2e.ts +++ b/apps/cli/tests/profiles/acp/tests/goal.expected.e2e.ts @@ -150,7 +150,7 @@ describe('same-session goal snapshot through the ACP automation driver', () => { // The wrap-up instruction is one plugin-sourced context injected after the // terminal tool result, and the model still answers inside the same turn. const wrapups = events.filter(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' && event.data.source.plugin === 'tool-goal') + && event.data.source.kind === 'tool-goal') expect(wrapups).toHaveLength(1) const wrapupText = wrapups.map(event => event.type === 'user/message' ? event.data.content : [])[0] expect(JSON.stringify(wrapupText)).toContain('') diff --git a/apps/cli/tests/profiles/headless/tests/compaction.e2e.ts b/apps/cli/tests/profiles/headless/tests/compaction.e2e.ts index 545d57577c..b2f470e3be 100644 --- a/apps/cli/tests/profiles/headless/tests/compaction.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/compaction.e2e.ts @@ -89,7 +89,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('compaction: a long session compa expect(summaryData.shadowedSeqs.length).toBeGreaterThan(0) expect(events.some(event => event.type === 'tool/result' && summaryData.shadowedSeqs.includes(event.seq) - && event.data.message.content[0].content.some(block => block.type === 'text' + && event.data.message.content.some(block => block.type === 'text' && block.text.includes('This is file number')))).toBe(true) // The conversation survived compaction: the agent produced a final answer diff --git a/apps/cli/tests/profiles/headless/tests/expected/goal-tools/stream-json.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/goal-tools/stream-json.expected.jsonl index 8d8ea28581..36fe8fd2d4 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/goal-tools/stream-json.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/goal-tools/stream-json.expected.jsonl @@ -2,28 +2,28 @@ {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":4,"time":0,"data":{"turn":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":5,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":6,"time":0,"data":{"turn":1,"step":1}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":8,"time":0,"data":{"content":[{"type":"text","text":"Probe strict-schema fillers against missing-goal revision 1, then create a durable goal to finish the snapshot proof and inspect it."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":10,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/context","seq":11,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":12,"time":0,"data":{"title":"Probe strict-schema fillers against miss","messageSeqs":[8],"source":{"kind":"fallback"}}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"Probe strict-schema fillers against missing-goal revision 1, then create a durable goal to finish the snapshot proof and inspect it.\"}]"}],"source":{"kind":"plugin","plugin":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"Probe strict-schema fillers against missing-goal revision 1, then create a durable goal to finish the snapshot proof and inspect it.\"}]"}],"source":{"kind":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":14,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_goal_probe","name":"update_goal","arguments":"{\"goal_id\":\"missing-goal\",\"revision\":1,\"action\":\"pause\",\"objective\":\"\",\"max_goal_rounds\":0,\"blocked_reason\":\"\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":15,"outputTokens":6},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"call_goal_probe","name":"update_goal","args":["{\"goal_id\":\"missing-goal\",\"revision\":1,\"action\":\"pause\",\"objective\":\"\",\"max_goal_rounds\":0,\"blocked_reason\":\"\"}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_goal_probe","name":"update_goal","arguments":"{\"goal_id\":\"missing-goal\",\"revision\":1,\"action\":\"pause\",\"objective\":\"\",\"max_goal_rounds\":0,\"blocked_reason\":\"\"}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":15,"outputTokens":6}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":15,"time":0,"data":{"turn":1,"step":1,"callId":"call_goal_probe","name":"update_goal","arguments":"{\"goal_id\":\"missing-goal\",\"revision\":1,\"action\":\"pause\",\"objective\":\"\",\"max_goal_rounds\":0,\"blocked_reason\":\"\"}"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":16,"time":0,"data":{"title":"Goal tool snapshot","messageSeqs":[8],"source":{"kind":"provider","provider":"session-title-first-prompt-llm","model":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":17,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_goal_probe"},"content":[{"type":"tool-result","toolCallId":"call_goal_probe","content":[{"type":"text","text":"Error: no current goal"}],"isError":true}],"role":"user","id":"{{sessionId}}"},"error":{"name":"GoalError","code":"GOAL_NOT_FOUND"}},"sourceEventSeqs":[15],"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":17,"time":0,"data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_goal_probe"},"toolCallId":"call_goal_probe","content":[{"type":"text","text":"Error: no current goal"}],"isError":true,"id":"{{sessionId}}"},"error":{"name":"GoalError","code":"GOAL_NOT_FOUND"}},"sourceEventSeqs":[15],"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":18,"time":0,"data":{"turn":1,"step":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":19,"time":0,"data":{"turn":1,"step":2}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":20,"time":0,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the headless goal-tool snapshot proof\",\"max_goal_rounds\":7}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":20,"outputTokens":8},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"call_goal_create","name":"create_goal","args":["{\"objective\":\"Finish the headless goal-tool snapshot proof\",\"max_goal_rounds\":7}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the headless goal-tool snapshot proof\",\"max_goal_rounds\":7}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":20,"outputTokens":8}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":21,"time":0,"data":{"turn":1,"step":2,"callId":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the headless goal-tool snapshot proof\",\"max_goal_rounds\":7}"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"goal/change","seq":22,"time":0,"data":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the headless goal-tool snapshot proof","phase":"active","maxGoalRounds":7},"roundsStarted":0,"createdAt":0,"updatedAt":0}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":23,"time":0,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_goal_create"},"content":[{"type":"tool-result","toolCallId":"call_goal_create","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":7},\"activation\":\"armed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[21],"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":23,"time":0,"data":{"turn":1,"step":2,"message":{"role":"tool","source":{"kind":"tool","callId":"call_goal_create"},"toolCallId":"call_goal_create","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":7},\"activation\":\"armed\"}"}],"isError":false,"id":"{{sessionId}}"}},"sourceEventSeqs":[21],"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":24,"time":0,"data":{"turn":1,"step":2}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":25,"time":0,"data":{"turn":1,"step":3}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":26,"time":0,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_goal_get","name":"get_goal","arguments":"{}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":30,"outputTokens":4},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"call_goal_get","name":"get_goal","args":["{}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_goal_get","name":"get_goal","arguments":"{}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":30,"outputTokens":4}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":27,"time":0,"data":{"turn":1,"step":3,"callId":"call_goal_get","name":"get_goal","arguments":"{}"}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":28,"time":0,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"call_goal_get"},"content":[{"type":"tool-result","toolCallId":"call_goal_get","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":7},\"activation\":\"armed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[27],"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":28,"time":0,"data":{"turn":1,"step":3,"message":{"role":"tool","source":{"kind":"tool","callId":"call_goal_get"},"toolCallId":"call_goal_get","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":7},\"activation\":\"armed\"}"}],"isError":false,"id":"{{sessionId}}"}},"sourceEventSeqs":[27],"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":29,"time":0,"data":{"turn":1,"step":3}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":30,"time":0,"data":{"turn":1,"step":4}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":31,"time":0,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"text","text":"GOAL READY"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":35,"outputTokens":2},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["GOAL READY"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"GOAL READY"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":35,"outputTokens":2}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}} diff --git a/apps/cli/tests/profiles/headless/tests/expected/invalid-credential/stream-json.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/invalid-credential/stream-json.expected.jsonl index cf4f395dd4..0f7431a36e 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/invalid-credential/stream-json.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/invalid-credential/stream-json.expected.jsonl @@ -2,13 +2,13 @@ {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":4,"time":0,"data":{"turn":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":5,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":6,"time":0,"data":{"turn":1,"step":1}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":8,"time":0,"data":{"content":[{"type":"text","text":"say pong"}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":10,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash","maxTokens":256000,"reasoningEffort":"high"},"adapterDefaults":{"reasoningEffort":true,"maxTokens":true},"tools":"{{tools}}"},"reason":"initial"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/context","seq":11,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash","contextWindow":1000000}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":12,"time":0,"data":{"title":"say pong","messageSeqs":[8],"source":{"kind":"fallback"}}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"say pong\"}]"}],"source":{"kind":"plugin","plugin":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"say pong\"}]"}],"source":{"kind":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/attempt","seq":14,"time":0,"data":{"turn":1,"step":1,"stream":[{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"llm-deepseek: the API key resolved from DEEPSEEK_API_KEY contains characters no HTTP header can carry; set DEEPSEEK_API_KEY to the raw key alone (the web Models page writes it)","code":"INVALID_CREDENTIAL"}}}}]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":15,"time":0,"data":{"turn":1,"step":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":16,"time":0,"data":{"turn":1,"reason":{"kind":"error","error":{"message":"llm-deepseek: the API key resolved from DEEPSEEK_API_KEY contains characters no HTTP header can carry; set DEEPSEEK_API_KEY to the raw key alone (the web Models page writes it)","code":"INVALID_CREDENTIAL"}}}}} diff --git a/apps/cli/tests/profiles/headless/tests/expected/missing-credential/stream-json.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/missing-credential/stream-json.expected.jsonl index b285bfab73..e8f421ae70 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/missing-credential/stream-json.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/missing-credential/stream-json.expected.jsonl @@ -2,13 +2,13 @@ {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":4,"time":0,"data":{"turn":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":5,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":6,"time":0,"data":{"turn":1,"step":1}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":8,"time":0,"data":{"content":[{"type":"text","text":"say pong"}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":10,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash","maxTokens":256000,"reasoningEffort":"high"},"adapterDefaults":{"reasoningEffort":true,"maxTokens":true},"tools":"{{tools}}"},"reason":"initial"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/context","seq":11,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash","contextWindow":1000000}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":12,"time":0,"data":{"title":"say pong","messageSeqs":[8],"source":{"kind":"fallback"}}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"say pong\"}]"}],"source":{"kind":"plugin","plugin":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"say pong\"}]"}],"source":{"kind":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/attempt","seq":14,"time":0,"data":{"turn":1,"step":1,"stream":[{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"llm-deepseek: no API key for provider route \"deepseek-official\"; store DEEPSEEK_API_KEY through the credentials service (the web Models page writes it), or export DEEPSEEK_API_KEY in the launching environment","code":"MISSING_CREDENTIAL"}}}}]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":15,"time":0,"data":{"turn":1,"step":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":16,"time":0,"data":{"turn":1,"reason":{"kind":"error","error":{"message":"llm-deepseek: no API key for provider route \"deepseek-official\"; store DEEPSEEK_API_KEY through the credentials service (the web Models page writes it), or export DEEPSEEK_API_KEY in the launching environment","code":"MISSING_CREDENTIAL"}}}}} diff --git a/apps/cli/tests/profiles/headless/tests/expected/provider-retry/stream-json.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/provider-retry/stream-json.expected.jsonl index cb83ea205a..bce6fb173d 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/provider-retry/stream-json.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/provider-retry/stream-json.expected.jsonl @@ -2,13 +2,13 @@ {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":4,"time":0,"data":{"turn":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":5,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":6,"time":0,"data":{"turn":1,"step":1}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":8,"time":0,"data":{"content":[{"type":"text","text":"retry the transient provider failure"}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":10,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/context","seq":11,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":12,"time":0,"data":{"title":"retry the transient provider failure","messageSeqs":[8],"source":{"kind":"fallback"}}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"retry the transient provider failure\"}]"}],"source":{"kind":"plugin","plugin":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"retry the transient provider failure\"}]"}],"source":{"kind":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/attempt","seq":14,"time":0,"data":{"turn":1,"step":1,"stream":[{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"snapshot transient failure","code":"RATE_LIMIT","status":429}}}}]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"llm/retry","seq":15,"time":0,"data":{"retryId":"{{sessionId}}","turn":1,"step":1,"provider":"deepseek-official","mode":"normal","policyKey":"[\"normal\",1,[\"RATE_LIMIT\"],1,1,0]","retry":1,"maxRetries":1,"delayMs":1,"failure":{"message":"snapshot transient failure","code":"RATE_LIMIT","status":429}}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"llm/retry-started","seq":16,"time":0,"data":{"retryId":"{{sessionId}}","turn":1,"step":1,"retry":1}}} diff --git a/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl index ac7306cfdd..a359220fbb 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl @@ -5,6 +5,7 @@ {"type":"user/message","data":{"content":[{"type":"text","text":"Start a background job."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"step/end","data":{"turn":1,"step":1}} {"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"subagent/catalog","data":{"version":0,"childId":"{{sessionId}}","childCreatedAt":0,"mode":"continuable","label":"descriptorless child"}} {"type":"session/end-seed","data":{}} {"type":"permission/preset","data":{"preset":"workspace-write"}} {"type":"sandbox/mode","data":{"mode":"workspace-write"}} @@ -21,9 +22,9 @@ {"type":"session/title","data":{"title":"Start a background job.","messageSeqs":[3],"source":{"kind":"fallback"}}} {"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"list-once","name":"list_agents","arguments":"{}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"list-once","name":"list_agents","args":["{}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"list-once","name":"list_agents","arguments":"{}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"} {"type":"tool/call","data":{"turn":2,"step":1,"callId":"list-once","name":"list_agents","arguments":"{}"}} -{"type":"tool/result","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"list-once"},"content":[{"type":"tool-result","toolCallId":"list-once","content":[{"type":"text","text":"{{sessionId}} [diagnostic: corrupt]"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[21],"surfaceOp":"append"} +{"type":"tool/result","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"list-once"},"content":[{"type":"tool-result","toolCallId":"list-once","content":[{"type":"text","text":"{{sessionId}} [inactive] — descriptorless child"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[22],"surfaceOp":"append"} {"type":"step/end","data":{"turn":2,"step":1}} {"type":"step/start","data":{"turn":2,"step":2}} -{"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"The stored subagent is unreadable. PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["The stored subagent is unreadable. PARENT_DONE"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"The stored subagent is unreadable. PARENT_DONE"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} +{"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"The catalogued subagent is ready. PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["The catalogued subagent is ready. PARENT_DONE"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"The catalogued subagent is ready. PARENT_DONE"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} {"type":"step/end","data":{"turn":2,"step":2}} {"type":"turn/end","data":{"turn":2,"reason":{"kind":"completed"}}} diff --git a/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/replay.override.json b/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/replay.override.json index 2b9facf71f..6d66bcf03d 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/replay.override.json +++ b/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/replay.override.json @@ -1 +1 @@ -[{"kind": "chunks", "chunks": [{"type": "block-start", "index": 0, "blockType": "tool-call"}, {"type": "tool-call-delta", "index": 0, "id": "list-once", "name": "list_agents", "argumentsDelta": "{}"}, {"type": "block-end", "index": 0, "block": {"type": "tool-call", "id": "list-once", "name": "list_agents", "arguments": "{}"}}, {"type": "usage", "usage": {"inputTokens": 10, "outputTokens": 5}}, {"type": "finish", "reason": {"kind": "tool-calls"}}]}, {"kind": "chunks", "chunks": [{"type": "block-start", "index": 0, "blockType": "text"}, {"type": "text-delta", "index": 0, "text": "The stored subagent is unreadable. PARENT_DONE"}, {"type": "block-end", "index": 0, "block": {"type": "text", "text": "The stored subagent is unreadable. PARENT_DONE"}}, {"type": "usage", "usage": {"inputTokens": 10, "outputTokens": 5}}, {"type": "finish", "reason": {"kind": "stop"}}]}] +[{"kind": "chunks", "chunks": [{"type": "block-start", "index": 0, "blockType": "tool-call"}, {"type": "tool-call-delta", "index": 0, "id": "list-once", "name": "list_agents", "argumentsDelta": "{}"}, {"type": "block-end", "index": 0, "block": {"type": "tool-call", "id": "list-once", "name": "list_agents", "arguments": "{}"}}, {"type": "usage", "usage": {"inputTokens": 10, "outputTokens": 5}}, {"type": "finish", "reason": {"kind": "tool-calls"}}]}, {"kind": "chunks", "chunks": [{"type": "block-start", "index": 0, "blockType": "text"}, {"type": "text-delta", "index": 0, "text": "The catalogued subagent is ready. PARENT_DONE"}, {"type": "block-end", "index": 0, "block": {"type": "text", "text": "The catalogued subagent is ready. PARENT_DONE"}}, {"type": "usage", "usage": {"inputTokens": 10, "outputTokens": 5}}, {"type": "finish", "reason": {"kind": "stop"}}]}] diff --git a/apps/cli/tests/profiles/headless/tests/expected/subagent-settlement/stream-json.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/subagent-settlement/stream-json.expected.jsonl index b027378207..3c8e6615eb 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/subagent-settlement/stream-json.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/subagent-settlement/stream-json.expected.jsonl @@ -2,18 +2,18 @@ {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":4,"time":0,"data":{"turn":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":5,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":6,"time":0,"data":{"turn":1,"step":1}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"system/message","seq":7,"time":0,"data":{"turn":1,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":8,"time":0,"data":{"content":[{"type":"text","text":"Start one continuable background subagent and answer from its completion notice. Do not call list_agents, send_message, job_output, or job_list."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":9,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":10,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/context","seq":11,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":12,"time":0,"data":{"title":"Start one continuable background subagen","messageSeqs":[8],"source":{"kind":"fallback"}}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"Start one continuable background subagent and answer from its completion notice. Do not call list_agents, send_message, job_output, or job_list.\"}]"}],"source":{"kind":"plugin","plugin":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title-llm-request","seq":13,"time":0,"data":{"titleProvider":"session-title-first-prompt-llm","messageSeqs":[8],"route":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"Create a concise title for an AI coding-assistant session from the supplied human messages.\nReturn only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.\nUse the language of the messages.\nAim for about 5 words in non-CJK languages or 10 CJK characters.","messages":[{"content":[{"type":"text","text":"Generate the session title from this JSON array of human messages:\n[{\"seq\":8,\"text\":\"Start one continuable background subagent and answer from its completion notice. Do not call list_agents, send_message, job_output, or job_list.\"}]"}],"source":{"kind":"dsh-session-title-llm"},"role":"user","id":"{{sessionId}}"}],"maxTokens":64}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":14,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"start-child","name":"subagent","arguments":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call send_message.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"start-child","name":"subagent","args":["{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call send_message.\"}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"start-child","name":"subagent","arguments":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call send_message.\"}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":15,"time":0,"data":{"turn":1,"step":1,"callId":"start-child","name":"subagent","arguments":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call send_message.\"}"}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":16,"time":0,"data":{"title":"Subagent settlement","messageSeqs":[8],"source":{"kind":"provider","provider":"session-title-first-prompt-llm","model":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"subagent/catalog","seq":17,"time":0,"data":{"version":0,"childId":"{{sessionId}}","childCreatedAt":0,"mode":"continuable","label":"Return child result"}}} -{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":18,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"start-child"},"content":[{"type":"tool-result","toolCallId":"start-child","content":[{"type":"text","text":"started subagent {{sessionId}}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[15],"surfaceOp":"append"}} +{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":18,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"start-child"},"content":[{"type":"text","text":"started subagent {{sessionId}}"}],"role":"tool","toolCallId":"start-child","isError":false,"id":"{{sessionId}}"}},"sourceEventSeqs":[15],"surfaceOp":"append"}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":19,"time":0,"data":{"turn":1,"step":1}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":20,"time":0,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Background subagent {{sessionId}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_RESULT"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{sessionId}} finished and will do no further work unless you send it more.","senderSessionId":"{{sessionId}}"},"role":"user","id":"{{sessionId}}"}]}}} {"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":21,"time":0,"data":{"turn":1,"step":2}}} diff --git a/apps/cli/tests/profiles/headless/tests/fixtures/team-llm.mjs b/apps/cli/tests/profiles/headless/tests/fixtures/team-llm.mjs index 8319ed9539..3e2da6553f 100644 --- a/apps/cli/tests/profiles/headless/tests/fixtures/team-llm.mjs +++ b/apps/cli/tests/profiles/headless/tests/fixtures/team-llm.mjs @@ -28,11 +28,9 @@ function hasTaskAction(messages, action) { } function latestToolText(messages) { - const message = messages.findLast(candidate => candidate.content.some(block => block.type === 'tool-result')) + const message = messages.findLast(candidate => candidate.role === 'tool') if (message === undefined) return '' - return message.content.flatMap(block => block.type === 'tool-result' - ? block.content.filter(item => item.type === 'text').map(item => item.text) - : []).join('\n') + return message.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('\n') } function toolChunks(specs) { diff --git a/apps/cli/tests/profiles/headless/tests/full-loop.e2e.ts b/apps/cli/tests/profiles/headless/tests/full-loop.e2e.ts index 6816c60f61..bbacf9dc15 100644 --- a/apps/cli/tests/profiles/headless/tests/full-loop.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/full-loop.e2e.ts @@ -41,7 +41,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('full loop: real model + real bas const results = events.filter(event => event.type === 'tool/result') const resultTexts = results.flatMap(event => - event.data.message.content[0].content.filter(block => block.type === 'text').map(block => block.text)) + event.data.message.content.filter(block => block.type === 'text').map(block => block.text)) expect(resultTexts.some(text => text.includes('e2e-ok'))).toBe(true) expect(finalText(events)).toContain('e2e-ok') diff --git a/apps/cli/tests/profiles/headless/tests/headless.expected.e2e.ts b/apps/cli/tests/profiles/headless/tests/headless.expected.e2e.ts index 62bccb3b29..4724981169 100644 --- a/apps/cli/tests/profiles/headless/tests/headless.expected.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/headless.expected.e2e.ts @@ -234,10 +234,12 @@ async function persistedLogs(cwd: string, root: string = join(cwd, '.sessions')) describe('headless stream-json snapshots', () => { - it('runs one task through the product headless profile command', async () => { + it.each(['src', 'lib'] as const)('runs one task through the product headless profile command (%s)', async (mode) => { const task = 'Prove the product headless profile path with one real tool round trip.' const result = await runLoaderSmoke({ label: 'product headless profile snapshot', + mode, + sourceImport: 'tsx/esm', tempDirPrefix: 'headless-snapshot-profile-', binScript: dshBinScript, configPath: headlessOverlayPath, @@ -925,8 +927,7 @@ describe('headless stream-json snapshots', () => { }) const probeData = probeResult?.data as JsonObject | undefined const probeMessage = probeData?.message as JsonObject | undefined - const probeContent = probeMessage?.content as JsonObject[] | undefined - expect(probeContent?.[0]?.isError).toBe(true) + expect(probeMessage?.isError).toBe(true) expect((probeData?.error as JsonObject | undefined)?.code).toBe('GOAL_NOT_FOUND') const goalChanges = records.filter(record => record.type === 'goal/change') expect(goalChanges).toHaveLength(1) diff --git a/apps/cli/tests/profiles/headless/tests/semantic-checkpoint.expected.e2e.ts b/apps/cli/tests/profiles/headless/tests/semantic-checkpoint.expected.e2e.ts index c5d679484e..e2815248f0 100644 --- a/apps/cli/tests/profiles/headless/tests/semantic-checkpoint.expected.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/semantic-checkpoint.expected.e2e.ts @@ -52,7 +52,7 @@ async function seedInterruptedSession(root: string, cwd: string): Promise event.type === 'tool/result') expect(results).toHaveLength(1) const toolResult = results[0]!.data - expect(toolResult.message.content).toHaveLength(1) - const block = toolResult.message.content[0] - expect(block).toMatchObject({ type: 'tool-result', toolCallId: 'cli-smoke-call' }) + const message = toolResult.message + expect(message).toMatchObject({ role: 'tool', toolCallId: 'cli-smoke-call' }) if (toolResult.error !== undefined) { expect(toolResult.error).toMatchObject({ name: 'SandboxUnavailableError', code: 'SANDBOX_UNAVAILABLE' }) - expect(block.isError).toBe(true) + expect(message.isError).toBe(true) } else { - expect(block.isError).not.toBe(true) - expect(block.content.filter(part => part.type === 'text').map(part => part.text).join('')) + expect(message.isError).not.toBe(true) + expect(message.content.filter(part => part.type === 'text').map(part => part.text).join('')) .toContain('CLI_TOOL_ROUND_TRIP') } expect(evidence.events.filter(event => event.type === 'turn/end').map(event => event.data.reason)) diff --git a/apps/cli/tests/profiles/headless/tests/subagent-diagnostic.expected.e2e.ts b/apps/cli/tests/profiles/headless/tests/subagent-diagnostic.expected.e2e.ts index 7cdb9a2e36..cec8642309 100644 --- a/apps/cli/tests/profiles/headless/tests/subagent-diagnostic.expected.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/subagent-diagnostic.expected.e2e.ts @@ -1,7 +1,6 @@ /** - * Assembled-app regression: a persisted `origin: 'subagent'` child whose log - * carries no descriptor event is surfaced by `list_agents` as a - * `[diagnostic: corrupt]` row instead of being silently dropped. + * Assembled-app regression: a parent-owned catalog event remains sufficient + * for direct discovery when the persisted child has no descriptor event. */ import { readFile, readdir, writeFile } from 'node:fs/promises' @@ -42,11 +41,10 @@ async function expectSession(actual: string, expectedPath: string): Promise { +async function seedCataloguedDescriptorlessChild(root: string, cwd: string): Promise { const ctx = new Context() await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' }) const parentMeta: SessionHeader = { @@ -62,12 +60,24 @@ async function seedDescriptorlessChild(root: string, cwd: string): Promise { type: 'step/start', seq: SessionSeq(1), time: 11, data: { turn: 1, step: 1 } }, { type: 'system/message', seq: SessionSeq(2), time: 12, - data: { turn: 1, step: 1, message: createMessage({ role: 'system', content: [], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' } }) }, + data: { turn: 1, step: 1, message: createMessage({ role: 'system', content: [], source: { kind: 'system-prompt' } }) }, surfaceOp: 'append', }, { type: 'user/message', seq: SessionSeq(3), time: 13, data: createUserMessage({ content: [{ type: 'text', text: 'Start a background job.' }], source: { kind: 'user' } }), surfaceOp: 'append' }, { type: 'step/end', seq: SessionSeq(4), time: 14, data: { turn: 1, step: 1 } }, { type: 'turn/end', seq: SessionSeq(5), time: 15, data: { turn: 1, reason: { kind: 'completed' } } }, + { + type: 'subagent/catalog', + seq: SessionSeq(6), + time: 16, + data: { + version: 0, + childId, + childCreatedAt: 2, + mode: 'continuable', + label: 'descriptorless child', + }, + }, ] const childMeta: SessionHeader = { version: SESSION_FORMAT_VERSION, @@ -95,8 +105,8 @@ async function seedDescriptorlessChild(root: string, cwd: string): Promise } } -describe('descriptor-less cold child diagnostic snapshot', () => { - it('surfaces the unreadable child as a corrupt diagnostic through the assembled headless app', async () => { +describe('parent-owned cold child catalog snapshot', () => { + it('discovers a catalogued child without reading its descriptor through the assembled headless app', async () => { let cwd = '' const result = await runLoaderSmoke({ label: 'subagent diagnostic headless stream-json snapshot', @@ -112,7 +122,7 @@ describe('descriptor-less cold child diagnostic snapshot', () => { }, prepare: async (runCwd) => { cwd = runCwd - await seedDescriptorlessChild(join(runCwd, '.sessions'), runCwd) + await seedCataloguedDescriptorlessChild(join(runCwd, '.sessions'), runCwd) }, inspect: async (runCwd) => { const sessionsDir = join(runCwd, '.sessions') @@ -121,9 +131,10 @@ describe('descriptor-less cold child diagnostic snapshot', () => { const parent = logs.find(content => content.includes('"subagent-diagnostic-parent"')) if (parent === undefined) throw new Error('missing persisted parent log') - // THE model-visible fact: the descriptor-less child is reported, not - // silently dropped, and its reason is the corrupt classification. - expect(parent).toContain(`${childId} [diagnostic: corrupt]`) + // THE model-visible fact: the parent catalog supplies discovery even + // though consulting the descriptor-less child would classify it corrupt. + expect(parent).toContain(`${childId} [inactive] — descriptorless child`) + expect(parent).not.toContain('[diagnostic: corrupt]') const context: NormalizeContext = { sessionIds: [parentId, childId], cwd } const normalizedParent = normalizeSessionSnapshot(parent, context) @@ -139,7 +150,7 @@ describe('descriptor-less cold child diagnostic snapshot', () => { expect(records.at(-1)).toMatchObject({ type: 'result', sessionId: parentId, - output: 'The stored subagent is unreadable. PARENT_DONE', + output: 'The catalogued subagent is ready. PARENT_DONE', }) }, LOADER_SMOKE_TEST_TIMEOUT_MS) }) diff --git a/apps/cli/tests/profiles/headless/tests/subagent-inheritance.expected.e2e.ts b/apps/cli/tests/profiles/headless/tests/subagent-inheritance.expected.e2e.ts index 5317b3f347..4b5970cd9f 100644 --- a/apps/cli/tests/profiles/headless/tests/subagent-inheritance.expected.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/subagent-inheritance.expected.e2e.ts @@ -21,7 +21,8 @@ import { describe, expect, it } from 'vitest' const fixtureDir = fileURLToPath(new URL('./expected/subagent-inheritance', import.meta.url)) const replayOverride = join(fixtureDir, 'replay.override.json') -// Native replay preserves the V0 script's model outputs without migrating its pre-step user event. +// The released V3 child fixture replays through the V3-to-V4 migration, so its +// tool results lift and its plugin sources move onto producer kinds. const childReplay = join(fixtureDir, 'child.replay.v3.jsonl') const parentExpected = join(fixtureDir, 'parent.expected.jsonl') const childExpected = join(fixtureDir, 'child.expected.jsonl') @@ -59,7 +60,7 @@ async function seedReadOnlyParent(root: string, cwd: string): Promise { { type: 'step/start', seq: SessionSeq(1), time: 11, data: { turn: 1, step: 1 } }, { type: 'system/message', seq: SessionSeq(2), time: 12, - data: { turn: 1, step: 1, message: createMessage({ role: 'system', content: [], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' } }) }, + data: { turn: 1, step: 1, message: createMessage({ role: 'system', content: [], source: { kind: 'system-prompt' } }) }, surfaceOp: 'append', }, { type: 'user/message', seq: SessionSeq(3), time: 13, data: createUserMessage({ content: [{ type: 'text', text: 'Tighten this session to read-only.' }], source: { kind: 'user' } }), surfaceOp: 'append' }, @@ -140,11 +141,10 @@ describe('parent-only override inheritance snapshot', () => { const runtimeContexts = (content: string): string[] => content.trimEnd().split('\n').flatMap((line) => { const record = JSON.parse(line) as { type?: string - data?: { source?: { kind?: string; plugin?: string }; content?: Array<{ type?: string; text?: unknown }> } + data?: { source?: { kind?: string }; content?: Array<{ type?: string; text?: unknown }> } } if (record.type !== 'user/message' - || record.data?.source?.kind !== 'plugin' - || record.data.source.plugin !== '@deepseek-ai/dsh-system-prompt') return [] + || record.data?.source?.kind !== 'runtime-context') return [] return record.data.content?.flatMap(block => block.type === 'text' && typeof block.text === 'string' ? [block.text] : []) ?? [] }) const policyContexts = [...runtimeContexts(parent), ...runtimeContexts(child)] diff --git a/apps/cli/tests/profiles/headless/tests/workspace-context-resume.expected.e2e.ts b/apps/cli/tests/profiles/headless/tests/workspace-context-resume.expected.e2e.ts index cb4fdea338..b873ad7d77 100644 --- a/apps/cli/tests/profiles/headless/tests/workspace-context-resume.expected.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/workspace-context-resume.expected.e2e.ts @@ -90,7 +90,7 @@ async function seedVisibleBaseline( { type: 'step/start', seq: SessionSeq(1), time: 11, data: { turn: 1, step: 1 } }, { type: 'system/message', seq: SessionSeq(2), time: 12, - data: { turn: 1, step: 1, message: createMessage({ role: 'system', content: [], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' } }) }, + data: { turn: 1, step: 1, message: createMessage({ role: 'system', content: [], source: { kind: 'system-prompt' } }) }, surfaceOp: 'append', }, { diff --git a/apps/desktop/README.i18n.yaml b/apps/desktop/README.i18n.yaml index 0786e34605..455501862e 100644 --- a/apps/desktop/README.i18n.yaml +++ b/apps/desktop/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/desktop/README.md -README.md: f1239fa4df7b25a11c70c5cd1665535d7cfed32e -README.zh.md: 80654189dd03df514622e2710a806eeb40491fc5 +README.md: 6c9a6a8784732e6fa1369df5632391b789786b22 +README.zh.md: a0f2184d911eeab46902670cf992b6847e2bca31 diff --git a/apps/desktop/README.md b/apps/desktop/README.md index f1239fa4df..6c9a6a8784 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -48,6 +48,8 @@ Electron owns `$DSH_HOME/profiles/desktop`. Its `dependencies` contains packages The application preload exposes boot readiness, fatal startup reporting, and native directory selection. Product documents use the shared authenticated HTTP APIs and receive the Desktop marker, update presentation, and an action that opens native confirmation; they cannot choose artifacts or authorize installation. Plugin management uses the Web application's authenticated HTTP APIs. Electron serves update-dialog documents and assets locally at `dsh-app://shell/`, independently of Host readiness. Electron exposes no plugin-management IPC or separate management document. No renderer receives filesystem access, raw Electron IPC, a shell, or arbitrary pnpm arguments. +The `dsh-app://shell/` origin serves packaged update documents, scripts, and styles without contacting the Host. Static requests retain GET/HEAD, path-containment, and MIME handling; each update document keeps its isolated preload and owned-window IPC checks. + The product UI retains Web actions, including "Open In..." through the shared authenticated HTTP routes. Desktop uses Web's automatic directory-picker selection and initializes new profiles with the shared Web template's bundles. Electron chooses typed English or Chinese shell copy from its application locale and falls back to English. On Windows, the main document's language updates desktop menus, recovery and update prompts. The repository Client UI i18n gate checks desktop sources. diff --git a/apps/desktop/README.zh.md b/apps/desktop/README.zh.md index 80654189dd..a0f2184d91 100644 --- a/apps/desktop/README.zh.md +++ b/apps/desktop/README.zh.md @@ -48,6 +48,8 @@ Electron 拥有 `$DSH_HOME/profiles/desktop`。其 `dependencies` 包含 pnpm 应用 preload 暴露启动就绪、致命启动失败上报和原生目录选择。产品页面还获得 Desktop 标记、更新展示数据和打开原生确认的操作,不能选择安装产物或授权安装。插件管理使用 Web 应用经过认证的 HTTP API;Electron 在 `dsh-app://shell/` 本地提供更新弹窗文档和资源,不依赖 Host 就绪。Electron 不提供插件管理 IPC 或独立管理页面。 +`dsh-app://shell/` 无需联系 Host 即可提供打包的更新文档、脚本和样式。静态请求保留 GET/HEAD、路径范围和 MIME 处理;每个更新文档继续使用隔离 preload 和所属窗口的 IPC 校验。 + 产品 UI 保留 Web 操作,包括通过共享认证 HTTP 路由执行的“打开方式…”。Desktop 使用 Web 的自动目录选择机制,并以共享 Web 模板的 bundle 列表初始化新 profile。 Electron 根据应用语言选择类型化的英文或中文 shell 文案,并回退到英文。在 Windows 上,主文档的语言会更新桌面菜单、恢复与更新提示。仓库 Client UI i18n 检查覆盖桌面端源码。 diff --git a/apps/desktop/scripts/test-workspace-updates.ts b/apps/desktop/scripts/test-workspace-updates.ts index 53fbd5e43a..b768de5544 100644 --- a/apps/desktop/scripts/test-workspace-updates.ts +++ b/apps/desktop/scripts/test-workspace-updates.ts @@ -36,7 +36,7 @@ try { })) await cp(join(repo, 'apps/desktop/lib/types'), join(application, 'lib'), { recursive: true }) await cp(join(repo, 'apps/desktop/renderer'), join(application, 'renderer'), { recursive: true }) - for (const name of ['preload-app', 'preload', 'preload-mandatory', 'preload-update-dialog']) { + for (const name of ['preload-app', 'preload-mandatory', 'preload-update-dialog']) { await cp(join(repo, `apps/desktop/lib/${name}.cjs`), join(application, `lib/${name}.cjs`)) } await writeFile(join(application, 'package.json'), JSON.stringify({ name: 'desktop-update-qualification', version: manifest.version, type: 'module' })) diff --git a/apps/desktop/tests/main-startup.spec.ts b/apps/desktop/tests/main-startup.spec.ts index 7f2b4d7392..eaab0da9df 100644 --- a/apps/desktop/tests/main-startup.spec.ts +++ b/apps/desktop/tests/main-startup.spec.ts @@ -120,7 +120,7 @@ const harness = await vi.hoisted(async () => { whenReady: () => Promise.resolve(), getLocale: (): string => 'en-US', getVersion: () => '1.0.0', - getAppPath: () => 'desktop-test-app', + getAppPath: (): string => 'desktop-test-app', setAboutPanelOptions: vi.fn<(options: Electron.AboutPanelOptionsOptions) => void>(), requestSingleInstanceLock: () => true, exit: vi.fn(), @@ -310,6 +310,40 @@ afterEach(async () => { }) describe('desktop main startup', () => { + it('routes shell update documents and assets through the registered main protocol handler', async () => { + const root = join(import.meta.dirname, '..') + vi.spyOn(harness.app, 'getAppPath').mockReturnValue(root) + const web = await import('../src/web-document.ts') + const actual = await vi.importActual('../src/web-document.ts') + vi.mocked(web.serveWebDocument).mockImplementation(actual.serveWebDocument) + try { + await readyForUpdate() + const { protocol } = await import('electron') + const handler = vi.mocked(protocol).handle.mock.calls.at(-1)?.[1] + if (handler === undefined) throw new Error('main did not register its protocol handler') + for (const [name, mime] of [ + ['update-dialog.html', 'text/html'], ['update-dialog.css', 'text/css'], ['update-dialog.js', 'text/javascript'], + ['mandatory-update.html', 'text/html'], ['mandatory-update.css', 'text/css'], ['mandatory-update.js', 'text/javascript'], + ['update-close.svg', 'image/svg+xml'], + ] as const) { + const response = await handler(new Request(`dsh-app://shell/${name}`)) + expect(response.status).toBe(200) + expect(response.headers.get('content-type')).toContain(mime) + expect(await response.text()).toBe(readFileSync(join(root, 'renderer', name), 'utf8')) + } + const head = await handler(new Request('dsh-app://shell/update-dialog.html', { method: 'HEAD' })) + expect(head.status).toBe(200) + expect(await head.text()).toBe('') + expect((await handler(new Request('dsh-app://shell/update-dialog.html', { method: 'POST' }))).status).toBe(405) + expect((await handler(new Request('dsh-app://shell/%'))).status).toBe(400) + expect((await handler(new Request('dsh-app://shell/%2e%2e%2fpackage.json'))).status).toBe(403) + expect((await handler(new Request('dsh-app://shell/missing.html'))).status).toBe(404) + expect((await handler(new Request('dsh-app://other/update-dialog.html'))).status).toBe(404) + } finally { + vi.mocked(web.serveWebDocument).mockReset() + } + }) + it('serves shell dialogs and their assets without forwarding them to the Host', async () => { await readyForUpdate() const { serveWebDocument, forwardWebRequest } = await import('../src/web-document.ts') diff --git a/apps/web/tests/agent-preset-selection.e2e.ts b/apps/web/tests/agent-preset-selection.e2e.ts index a06c0da136..b7facbb598 100644 --- a/apps/web/tests/agent-preset-selection.e2e.ts +++ b/apps/web/tests/agent-preset-selection.e2e.ts @@ -34,6 +34,9 @@ const MENU_EXPECTED = join(SNAPSHOT_DIR, 'menu.expected.md') const HEADER_EXPECTED = join(SNAPSHOT_DIR, 'header.expected.md') const MODE = webSnapshotMode() const SEED_ID = 'agent-preset-selection-web-e2e' +const SEED_TIME = 1784974100000 +const SEEDED_CHILD_ID = sessionId('agent-preset-selection-child') +const SEEDED_CHILD_CREATED_AT = 1784974100100 /** A project skill only a preset that mounts `skill-filesystem` can discover. */ const SKILL_NAME = 'preset-catalog-demo' /** The preset whose rows resolve and then refuse to start. */ @@ -87,19 +90,18 @@ async function seedWorkspaceSkill(workspaceCwd: string): Promise { * @returns a tokenized session log ending on a closed turn. */ function seedLog(): string { - const time = 1784974100000 const at = (index: number, event: Record): string => - JSON.stringify({ ...event, seq: index, time: time + index }) + JSON.stringify({ ...event, seq: index, time: SEED_TIME + index }) return [ JSON.stringify({ type: 'session', version: SESSION_FORMAT_VERSION, id: '{{sessionId}}', - createdAt: time, cwd: '{{cwd}}/workspace', isSeeded: false, delegationDepth: 0, + createdAt: SEED_TIME, cwd: '{{cwd}}/workspace', isSeeded: false, delegationDepth: 0, }), at(0, { type: 'turn/start', data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user', rpcId: 'seed' } } } }), at(1, { type: 'step/start', data: { turn: 1, step: 1 } }), at(2, { type: 'system/message', - data: { turn: 1, step: 1, message: createSystemMessage('', '@deepseek-ai/dsh-system-prompt') }, + data: { turn: 1, step: 1, message: createSystemMessage('') }, surfaceOp: 'append', }), at(3, { @@ -114,7 +116,17 @@ function seedLog(): string { }), at(4, { type: 'session/title', data: { title: 'Seeded turn', messageSeqs: [3], source: { kind: 'fallback' } } }), at(5, { type: 'step/end', data: { turn: 1, step: 1 } }), - at(6, { type: 'turn/end', data: { turn: 1, reason: { kind: 'completed' } } }), + at(6, { + type: 'subagent/catalog', + data: { + version: 0, + childId: SEEDED_CHILD_ID, + childCreatedAt: SEEDED_CHILD_CREATED_AT, + mode: 'one-shot', + label: 'header order probe', + }, + }), + at(7, { type: 'turn/end', data: { turn: 1, reason: { kind: 'completed' } } }), ].join('\n') } @@ -125,13 +137,11 @@ function seedLog(): string { * @param parentId - the seeded session whose header the browser opens. */ async function seedSubagent(scaffold: WebScaffold, parentId: SessionId): Promise { - const childId = sessionId('agent-preset-selection-child') - const createdAt = 1784974100100 const header: SessionHeader = { version: SESSION_FORMAT_VERSION, - id: childId, + id: SEEDED_CHILD_ID, isSeeded: false, - createdAt, + createdAt: SEEDED_CHILD_CREATED_AT, cwd: scaffold.workspaceCwd, parentSession: parentId, origin: 'subagent', @@ -143,13 +153,13 @@ async function seedSubagent(scaffold: WebScaffold, parentId: SessionId): Promise { type: 'turn/start', seq: 0, - time: createdAt, + time: SEEDED_CHILD_CREATED_AT, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } }, }, { type: 'user/message', seq: 1, - time: createdAt + 1, + time: SEEDED_CHILD_CREATED_AT + 1, data: createUserMessage({ content: [{ type: 'text', text: 'Check the session-header action order.' }], source: { kind: 'user' }, @@ -159,7 +169,7 @@ async function seedSubagent(scaffold: WebScaffold, parentId: SessionId): Promise { type: 'subagent/descriptor', seq: 2, - time: createdAt + 2, + time: SEEDED_CHILD_CREATED_AT + 2, data: snapshotSubagentDescriptor({ mode: 'one-shot', provider: 'spawn', label: 'header order probe', }), @@ -167,7 +177,7 @@ async function seedSubagent(scaffold: WebScaffold, parentId: SessionId): Promise { type: 'turn/end', seq: 3, - time: createdAt + 3, + time: SEEDED_CHILD_CREATED_AT + 3, data: { turn: 1, reason: { kind: 'completed' } }, }, ] as SessionEvent[]) diff --git a/apps/web/tests/assembled-remote.ts b/apps/web/tests/assembled-remote.ts index 913b082ed3..75852bf6b4 100644 --- a/apps/web/tests/assembled-remote.ts +++ b/apps/web/tests/assembled-remote.ts @@ -158,7 +158,6 @@ export function createAssembledRemote(options: AssembledRemoteOptions = {}): Ass 'settings/canOpenAgentPresetDirectory': ok(true), 'settings/openSettingsDocument': ok({ opened: true }), 'settings/openAgentPresetDirectory': ok({ opened: true }), - 'subagents/list': ok({ entries: [], parentAvailable: true }), 'terminal/list': ok([]), 'skills/list': ok({ skills: [] }), 'session/canOpenWorkspacePath': ok(true), @@ -224,6 +223,11 @@ export function createAssembledRemote(options: AssembledRemoteOptions = {}): Ass return ok(undefined) }) mock.unary('session/list', () => ok({ items: structuredClone(sessions) })) + mock.unary('session/projections', (request: unknown) => { + const sessionId = recordString(recordValue(request, 'request'), 'sessionId') + const summary = sessions.find(candidate => candidate.sessionId === sessionId) + return ok(structuredClone(summary?.projections ?? fixture.control.value.projections[sessionId] ?? null)) + }) mock.unary('workspace/create', (request: unknown) => { const path = recordString(recordValue(request, 'request'), 'path') const existing = workspaces.find(workspace => workspace.path === path) diff --git a/apps/web/tests/chat-continuous-conversation.e2e.ts b/apps/web/tests/chat-continuous-conversation.e2e.ts index c539a96601..810336de88 100644 --- a/apps/web/tests/chat-continuous-conversation.e2e.ts +++ b/apps/web/tests/chat-continuous-conversation.e2e.ts @@ -156,10 +156,11 @@ function assistantText(event: Extract): string { - return event.data.message.content[0].content - .filter(block => block.type === 'text') - .map(block => block.text) - .join('') + let text = '' + for (const block of event.data.message.content) { + if (block.type === 'text') text += block.text + } + return text } function messageKey(event: SessionEvent<'user/message'>): string { @@ -315,7 +316,7 @@ describe('web e2e: continuous conversation grown through the composer', () => { }) expect(results[0]?.data.turn).toBe(spec.index) expect(results[0]?.data.message.source.callId).toBe(spec.callId) - expect(results[0]?.data.message.content[0].isError).toBe(false) + expect(results[0]?.data.message.isError).toBe(false) expect(toolResultText(results[0]!)).toBe(`${spec.toolResultMarker}\n`) const toolRow = page.locator(`[data-chat-call-id="${spec.callId}"]`) diff --git a/apps/web/tests/chat-scroll-contract.e2e.ts b/apps/web/tests/chat-scroll-contract.e2e.ts index 2a13b8ef3e..25a64d8c01 100644 --- a/apps/web/tests/chat-scroll-contract.e2e.ts +++ b/apps/web/tests/chat-scroll-contract.e2e.ts @@ -13,6 +13,7 @@ import { ToolCallId } from '@deepseek-ai/dsh-llm' import type { AssistantStreamFrame } from '@deepseek-ai/dsh-agent' import type { ReplayEntry, ReplayOverrideDoc } from '@deepseek-ai/dsh-llm-replay' import type { SessionEvent } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session' import { createChatScrollFixture, type ChatScrollFixture } from './chat-scroll-fixture.ts' import { launchWebScaffold, @@ -489,9 +490,9 @@ function assertClean(world: ScrollWorld): void { expect(world.tripwire.warnings).toEqual([]) } -it('generates a native V3 scroll seed with a protected system head and intact references', () => { +it('generates a current-format scroll seed with a protected system head and intact references', () => { const { header, events } = parseSeedFixture(HISTORY_FIXTURE.log) - expect(header.version).toBe(3) + expect(header.version).toBe(SESSION_FORMAT_VERSION) expect(events.slice(0, 5).map(event => event.type)).toEqual([ 'turn/start', 'step/start', 'system/message', 'user/message', 'session/title', ]) diff --git a/apps/web/tests/chat-scroll-fixture.ts b/apps/web/tests/chat-scroll-fixture.ts index 34ebcc8d1b..109a4bcbe0 100644 --- a/apps/web/tests/chat-scroll-fixture.ts +++ b/apps/web/tests/chat-scroll-fixture.ts @@ -69,10 +69,7 @@ function appendSystemPrompt(session: Session, turn: number, step: number): void session.append('system/message', { turn, step, - message: createSystemMessage( - 'Synthetic chat-scroll system prompt.', - '@deepseek-ai/dsh-system-prompt', - ), + message: createSystemMessage('Synthetic chat-scroll system prompt.'), }, { surfaceOp: 'append' }) } diff --git a/apps/web/tests/complex-history.perf.ts b/apps/web/tests/complex-history.perf.ts index faa0146134..c4bfeff440 100644 --- a/apps/web/tests/complex-history.perf.ts +++ b/apps/web/tests/complex-history.perf.ts @@ -201,10 +201,7 @@ function appendSystemPrompt(session: Session, turn: number, step: number): void session.append('system/message', { turn, step, - message: createSystemMessage( - 'Synthetic performance system prompt.', - '@deepseek-ai/dsh-system-prompt', - ), + message: createSystemMessage('Synthetic performance system prompt.'), }, { surfaceOp: 'append' }) } @@ -1012,9 +1009,9 @@ async function continueConversation( if (toolResult?.type !== 'tool/result') { throw new Error(`continued turn ${String(index)} did not log its tool result`) } - const resultBlock = toolResult.data.message.content.find(block => block.type === 'tool-result') - expect(resultBlock?.isError).toBe(false) - expect(resultBlock?.content + const message = toolResult.data.message + expect(message.isError).toBe(false) + expect(message.content .filter(block => block.type === 'text') .map(block => block.text) .join('')).toContain(spec.toolResultMarker) diff --git a/apps/web/tests/expected/cordis-history/ui.expected.md b/apps/web/tests/expected/cordis-history/ui.expected.md index 46e291221f..2ddd03bddb 100644 --- a/apps/web/tests/expected/cordis-history/ui.expected.md +++ b/apps/web/tests/expected/cordis-history/ui.expected.md @@ -13,7 +13,7 @@ - text: "Use only Cordis tools. First call cordis_inspect_self with no arguments. Then call cordis_define with plugin kind \"new\", idPrefix \"snap\", name \"snapshot noop\", purpose \"does nothing, for the snapshot\", code.host exactly \"return { name: \\\"snapshot-noop\\\", apply(ctx) {} }\" and code.client exactly \"return { inject: [\\\"slots\\\"], apply(ctx) { ctx.slots.register({ name: \\\"shell.overlay\\\", id: \\\"snapshot-probe\\\" }, () => React.createElement(\\\"div\\\", { \\\"data-snapshot-probe\\\": \\\"loaded\\\" })) } }\". Read its returned pluginId and packageId, then call cordis_run with those exact IDs and mode \"run\". After the run request returns, reply exactly CORDIS_UI_READY and stop. 9/1 {{clock}}" - button "Copy" - button "3 tool calls" [expanded] -- button "Context injection @deepseek-ai/dsh-system-prompt" +- button "Context injection runtime-context" - button "Think I will inspect the current Session's dynamic Cordis Plugins before defining the snapshot Package." - button "Inspect plugins 0 dynamic plugins" - button "Think No dynamic Plugins are present, so I will define the requested Host and Client Package." diff --git a/apps/web/tests/expected/fork-mid-turn/ui.expected.md b/apps/web/tests/expected/fork-mid-turn/ui.expected.md new file mode 100644 index 0000000000..1350afec53 --- /dev/null +++ b/apps/web/tests/expected/fork-mid-turn/ui.expected.md @@ -0,0 +1,18 @@ +- button "System prompt" +- text: "Use the read tool twice in one assistant message: read a.txt and b.txt. Then reply with the single word DONE and stop. {{clock}}" +- button "Copy" +- button "Think The user wants me to read a.txt and b.txt, then reply with \"DONE\". Let me do both reads in parallel." +- text: Failed +- 'button "Read The history inherited by this branch records this tool call starting but does not include its result. The parent session may have completed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly."' +- text: Failed +- 'button "Tool call The history inherited by this branch has no record of this tool call starting. The parent session may have executed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly."' +- button "System prompt" +- text: FORK_BRANCH_USER Summarize what this branch knows about the reads. {{clock}} +- button "Copy" +- button "Thought for a while" +- paragraph: FORK_BRANCH_FIRST this branch has no read results, so I would check what the parent completed before retrying. FORK_BRANCH_DONE. +- button "Copy" +- button "Good response" +- button "Bad response" +- button "Branch into a new conversation" +- text: {{clock}} diff --git a/apps/web/tests/expected/github-ready-review/conversation-expanded.expected.md b/apps/web/tests/expected/github-ready-review/conversation-expanded.expected.md index 925804d353..4abbc3d013 100644 --- a/apps/web/tests/expected/github-ready-review/conversation-expanded.expected.md +++ b/apps/web/tests/expected/github-ready-review/conversation-expanded.expected.md @@ -19,7 +19,7 @@ - button "System prompt" - button "Thought for a while" [expanded] - button "Context injection webhook github webhook handled by review-pr-when-ready" -- button "Context injection @deepseek-ai/dsh-system-prompt" +- button "Context injection runtime-context" - paragraph: "Review complete: no actionable findings." - button "Copy" - button "Good response" diff --git a/apps/web/tests/expected/skill-user-invoke/ui-expanded.expected.md b/apps/web/tests/expected/skill-user-invoke/ui-expanded.expected.md index a5b5ed2089..1876f63c32 100644 --- a/apps/web/tests/expected/skill-user-invoke/ui-expanded.expected.md +++ b/apps/web/tests/expected/skill-user-invoke/ui-expanded.expected.md @@ -12,7 +12,7 @@ - text: and confirm the fixture wiring {{clock}} - button "Copy" - button "Thought for a while" [expanded] -- button "Context injection @deepseek-ai/dsh-system-prompt" +- button "Context injection runtime-context" - button "Context injection user-invoke-demo" - paragraph: USER_INVOKE_REPLY acknowledged; following the injected skill. - button "Copy" diff --git a/apps/web/tests/expected/steer-all/mid-steer.expected.md b/apps/web/tests/expected/steer-all/mid-steer.expected.md index d764e841f4..f3e9564660 100644 --- a/apps/web/tests/expected/steer-all/mid-steer.expected.md +++ b/apps/web/tests/expected/steer-all/mid-steer.expected.md @@ -9,7 +9,7 @@ - button "System prompt" - text: Use the ask_user_question tool to ask me exactly one question with id "checkpoint", question "Ready to continue?", header "Checkpoint", and options labeled "Yes" and "No". After I answer, reply with one short sentence acknowledging my answer and stop. {{clock}} - button "Copy" -- button "Context injection @deepseek-ai/dsh-system-prompt" +- button "Context injection runtime-context" - button "Think The user wants me to ask them a checkpoint question first, then continue with whatever they interject. Let me do exactly that." - status: Deep diving... - text: "Interjection: include the word BANANA in your final reply." diff --git a/apps/web/tests/expected/steer-all/settled-expanded.expected.md b/apps/web/tests/expected/steer-all/settled-expanded.expected.md index ffbad238a7..9538b35054 100644 --- a/apps/web/tests/expected/steer-all/settled-expanded.expected.md +++ b/apps/web/tests/expected/steer-all/settled-expanded.expected.md @@ -10,7 +10,7 @@ - text: Use the ask_user_question tool to ask me exactly one question with id "checkpoint", question "Ready to continue?", header "Checkpoint", and options labeled "Yes" and "No". After I answer, reply with one short sentence acknowledging my answer and stop. {{clock}} - button "Copy" - button "1 tool call" [expanded] -- button "Context injection @deepseek-ai/dsh-system-prompt" +- button "Context injection runtime-context" - button "Think The user wants me to ask them a checkpoint question first, then continue with whatever they interject. Let me do exactly that." - button "Ask question 1/1 answered" - text: "Interjection: include the word BANANA in your final reply. {{clock}}" diff --git a/apps/web/tests/file-upload-round.e2e.ts b/apps/web/tests/file-upload-round.e2e.ts index c25211dd13..7ff564de92 100644 --- a/apps/web/tests/file-upload-round.e2e.ts +++ b/apps/web/tests/file-upload-round.e2e.ts @@ -318,9 +318,9 @@ describe('web e2e: generic file upload through the real assembly', () => { event.type === 'tool/result' && event.data.message.source.callId === readCall.data.callId, ) if (readResult === undefined) throw new Error('the read call produced no durable result') - const content = readResult.data.message.content[0] - expect(content.isError).toBe(false) - expect(content.content.filter(block => block.type === 'text').map(block => block.text).join('')) + const message = readResult.data.message + expect(message.isError).toBe(false) + expect(message.content.filter(block => block.type === 'text').map(block => block.text).join('')) .toContain('UPLOAD_ROUND_OK') const turnEnds = sessionEvents.filter(event => event.type === 'turn/end') diff --git a/apps/web/tests/fixtures/assembled-remote.fixture.json b/apps/web/tests/fixtures/assembled-remote.fixture.json index e147b1f192..7a414d0a07 100644 --- a/apps/web/tests/fixtures/assembled-remote.fixture.json +++ b/apps/web/tests/fixtures/assembled-remote.fixture.json @@ -940,25 +940,20 @@ "turn": 52, "step": 0, "message": { + "id": "e9bbfe6c-96f3-44b6-b65c-89997783be1e", + "role": "tool", + "toolCallId": "fx-call-52", "source": { "kind": "tool", "callId": "fx-call-52" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-52", - "content": [ - { - "type": "text", - "text": "ECHO: TURN 52" - } - ], - "isError": false + "type": "text", + "text": "ECHO: TURN 52" } ], - "role": "user", - "id": "e9bbfe6c-96f3-44b6-b65c-89997783be1e" + "isError": false } } } @@ -1902,25 +1897,20 @@ "turn": 57, "step": 0, "message": { + "id": "652931ce-6eb0-4400-8173-9735b82fdf8e", + "role": "tool", + "toolCallId": "fx-call-57", "source": { "kind": "tool", "callId": "fx-call-57" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-57", - "content": [ - { - "type": "text", - "text": "ECHO: TURN 57" - } - ], - "isError": false + "type": "text", + "text": "ECHO: TURN 57" } ], - "role": "user", - "id": "652931ce-6eb0-4400-8173-9735b82fdf8e" + "isError": false } } } @@ -2560,25 +2550,20 @@ "turn": 60, "step": 0, "message": { + "id": "aa4c1898-7bec-4831-8ba1-0700f4ae897e", + "role": "tool", + "toolCallId": "fx-call-60", "source": { "kind": "tool", "callId": "fx-call-60" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-60", - "content": [ - { - "type": "text", - "text": "total 2\ndrwxr-xr-x fixture\n-rw-r--r-- demo.txt" - } - ], - "isError": false + "type": "text", + "text": "total 2\ndrwxr-xr-x fixture\n-rw-r--r-- demo.txt" } ], - "role": "user", - "id": "aa4c1898-7bec-4831-8ba1-0700f4ae897e" + "isError": false } } } @@ -2764,25 +2749,20 @@ "turn": 61, "step": 0, "message": { + "id": "4eedd943-773b-43d3-a104-e13550015670", + "role": "tool", + "toolCallId": "fx-call-61", "source": { "kind": "tool", "callId": "fx-call-61" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-61", - "content": [ - { - "type": "text", - "text": "wrote notes/demo.txt" - } - ], - "isError": false + "type": "text", + "text": "wrote notes/demo.txt" } ], - "role": "user", - "id": "4eedd943-773b-43d3-a104-e13550015670" + "isError": false }, "meta": { "diffs": [ @@ -2977,25 +2957,20 @@ "turn": 62, "step": 0, "message": { + "id": "37d72542-2cbc-4821-8897-329da97fe462", + "role": "tool", + "toolCallId": "fx-call-62", "source": { "kind": "tool", "callId": "fx-call-62" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-62", - "content": [ - { - "type": "text", - "text": "已编辑" - } - ], - "isError": false + "type": "text", + "text": "已编辑" } ], - "role": "user", - "id": "37d72542-2cbc-4821-8897-329da97fe462" + "isError": false }, "meta": { "diffs": [ @@ -3190,25 +3165,20 @@ "turn": 63, "step": 0, "message": { + "id": "0d0c76cf-f5b2-4f77-97cb-b0b66a67d135", + "role": "tool", + "toolCallId": "fx-call-63", "source": { "kind": "tool", "callId": "fx-call-63" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-63", - "content": [ - { - "type": "text", - "text": "已写入" - } - ], - "isError": false + "type": "text", + "text": "已写入" } ], - "role": "user", - "id": "0d0c76cf-f5b2-4f77-97cb-b0b66a67d135" + "isError": false }, "meta": { "diffs": [ @@ -3403,25 +3373,20 @@ "turn": 64, "step": 0, "message": { + "id": "11a489c7-466c-45ba-a5de-228fecd455f2", + "role": "tool", + "toolCallId": "fx-call-64", "source": { "kind": "tool", "callId": "fx-call-64" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-64", - "content": [ - { - "type": "text", - "text": "已编辑" - } - ], - "isError": false + "type": "text", + "text": "已编辑" } ], - "role": "user", - "id": "11a489c7-466c-45ba-a5de-228fecd455f2" + "isError": false }, "meta": { "diffs": [ @@ -3746,25 +3711,20 @@ "turn": 65, "step": 0, "message": { + "id": "ca689e1a-ebfb-4465-b187-43c3490abb9b", + "role": "tool", + "toolCallId": "fx-call-65", "source": { "kind": "tool", "callId": "fx-call-65" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-65", - "content": [ - { - "type": "text", - "text": "{\"listing\":\"demo.txt\\nnew-demo.txt\",\"demo\":\"hello fixture\\n\"}" - } - ], - "isError": false + "type": "text", + "text": "{\"listing\":\"demo.txt\\nnew-demo.txt\",\"demo\":\"hello fixture\\n\"}" } ], - "role": "user", - "id": "ca689e1a-ebfb-4465-b187-43c3490abb9b" + "isError": false } } } @@ -3950,25 +3910,20 @@ "turn": 66, "step": 0, "message": { + "id": "0da2afe6-5036-4d36-b9f3-ff562585507f", + "role": "tool", + "toolCallId": "fx-call-66", "source": { "kind": "tool", "callId": "fx-call-66" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-66", - "content": [ - { - "type": "text", - "text": "\u001b[1mRunning 4 checks\u001b[0m\n\u001b[32m✓\u001b[0m typecheck 1.82s\n\u001b[32m✓\u001b[0m lint 0.94s\n\u001b[32m✓\u001b[0m duplication 2.10s\n\u001b[31m✗\u001b[0m unit 8.41s\n\n\u001b[90mpackages/client/ui-primitives/tests/terminal-block.client.spec.tsx\u001b[0m\n \u001b[31mFAIL\u001b[0m caps output at the configured line budget\n expected 16 lines, received 24\n\nNAME LINES BRANCHES FUNCTIONS UNCOVERED\nTerminalBlock.tsx 100% 100% 100% -\nansi.ts 100% 100% 100% -\nclipboard.ts 100% 100% 100% -\nCodeBlock.tsx 98.4% 96.2% 100% 41-43\nhighlight.ts 100% 100% 100% -\nPill.tsx 100% 100% 100% -\nStateDot.tsx 100% 100% 100% -\nmarkdown/Markdown.tsx 100% 100% 100% -\n\n\u001b[31m1 of 4 checks failed\u001b[0m\n[exit code: 1]" - } - ], - "isError": false + "type": "text", + "text": "\u001b[1mRunning 4 checks\u001b[0m\n\u001b[32m✓\u001b[0m typecheck 1.82s\n\u001b[32m✓\u001b[0m lint 0.94s\n\u001b[32m✓\u001b[0m duplication 2.10s\n\u001b[31m✗\u001b[0m unit 8.41s\n\n\u001b[90mpackages/client/ui-primitives/tests/terminal-block.client.spec.tsx\u001b[0m\n \u001b[31mFAIL\u001b[0m caps output at the configured line budget\n expected 16 lines, received 24\n\nNAME LINES BRANCHES FUNCTIONS UNCOVERED\nTerminalBlock.tsx 100% 100% 100% -\nansi.ts 100% 100% 100% -\nclipboard.ts 100% 100% 100% -\nCodeBlock.tsx 98.4% 96.2% 100% 41-43\nhighlight.ts 100% 100% 100% -\nPill.tsx 100% 100% 100% -\nStateDot.tsx 100% 100% 100% -\nmarkdown/Markdown.tsx 100% 100% 100% -\n\n\u001b[31m1 of 4 checks failed\u001b[0m\n[exit code: 1]" } ], - "role": "user", - "id": "0da2afe6-5036-4d36-b9f3-ff562585507f" + "isError": false } } } @@ -4154,25 +4109,20 @@ "turn": 67, "step": 0, "message": { + "id": "9a3df388-356c-4440-b0bf-b09e0dda0387", + "role": "tool", + "toolCallId": "fx-call-67", "source": { "kind": "tool", "callId": "fx-call-67" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-67", - "content": [ - { - "type": "text", - "text": "Found 9 of 42 matches\n\npackages/client/ui-primitives/src/SearchBlock.tsx\nLine 16: export const DEFAULT_SEARCH_MAX_LINES = 16\nLine 138: export function SearchBlock(props: SearchBlockProps) {\nLine 141: const [collapsed, setCollapsed] = useState>(() => new Set())\npackages/client/ui-tool/src/client/tool/models/search-card-model.ts\nLine 45: export const CHAT_SEARCH_MAX_LINES = 8\nLine 130: export function searchCardModel(block: ToolCallBlock): SearchCardModel | null {\npackages/client/ui-tool/src/client/tool/toolviews/search-row.tsx\nLine 34: export function SearchRow({ toolName, block, inspect, t }: SearchRowProps) {\nLine 36: const search = searchCardModel(block)\nLine 56: search={search}\nLine 78: yield ctx.slots.register({ name: 'tool.call.toolview', key: 'grep', locale: NS }, SearchRow)\n\n(Full grep result stored at: fixture://spill/grep-66. Read it to see every match.)" - } - ], - "isError": false + "type": "text", + "text": "Found 9 of 42 matches\n\npackages/client/ui-primitives/src/SearchBlock.tsx\nLine 16: export const DEFAULT_SEARCH_MAX_LINES = 16\nLine 138: export function SearchBlock(props: SearchBlockProps) {\nLine 141: const [collapsed, setCollapsed] = useState>(() => new Set())\npackages/client/ui-tool/src/client/tool/models/search-card-model.ts\nLine 45: export const CHAT_SEARCH_MAX_LINES = 8\nLine 130: export function searchCardModel(block: ToolCallBlock): SearchCardModel | null {\npackages/client/ui-tool/src/client/tool/toolviews/search-row.tsx\nLine 34: export function SearchRow({ toolName, block, inspect, t }: SearchRowProps) {\nLine 36: const search = searchCardModel(block)\nLine 56: search={search}\nLine 78: yield ctx.slots.register({ name: 'tool.call.toolview', key: 'grep', locale: NS }, SearchRow)\n\n(Full grep result stored at: fixture://spill/grep-66. Read it to see every match.)" } ], - "role": "user", - "id": "9a3df388-356c-4440-b0bf-b09e0dda0387" + "isError": false }, "meta": { "shape": "matches", @@ -4416,25 +4366,20 @@ "turn": 68, "step": 0, "message": { + "id": "e6d88943-d180-472b-9c1b-d59a21a50ab9", + "role": "tool", + "toolCallId": "fx-call-68", "source": { "kind": "tool", "callId": "fx-call-68" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-68", - "content": [ - { - "type": "text", - "text": "packages/client/ui-primitives/src/SearchBlock.tsx\npackages/client/ui-primitives/src/SearchBlock.module.css\npackages/client/ui-tool/src/client/tool/models/search-card-model.ts\npackages/client/ui-tool/src/client/tool/toolviews/search-row.tsx\npackages/client/ui-tool/tests/search-card.client.spec.tsx\n\n(Showing 5 of 23 paths. Full sorted result stored at: fixture://spill/glob-67. Read it to see every path.)" - } - ], - "isError": false + "type": "text", + "text": "packages/client/ui-primitives/src/SearchBlock.tsx\npackages/client/ui-primitives/src/SearchBlock.module.css\npackages/client/ui-tool/src/client/tool/models/search-card-model.ts\npackages/client/ui-tool/src/client/tool/toolviews/search-row.tsx\npackages/client/ui-tool/tests/search-card.client.spec.tsx\n\n(Showing 5 of 23 paths. Full sorted result stored at: fixture://spill/glob-67. Read it to see every path.)" } ], - "role": "user", - "id": "e6d88943-d180-472b-9c1b-d59a21a50ab9" + "isError": false }, "meta": { "shape": "paths", @@ -4632,25 +4577,20 @@ "turn": 69, "step": 0, "message": { + "id": "937c02dd-63d8-4106-9310-a9df2055f0e9", + "role": "tool", + "toolCallId": "fx-call-69", "source": { "kind": "tool", "callId": "fx-call-69" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-69", - "content": [ - { - "type": "text", - "text": "packages/client/ui-primitives/src/ReadBlock.tsx\nfile\n\n41: export interface ReadBlockProps {\n42: label?: string | undefined\n43: lines: readonly ReadBlockLine[]\n44: totalLines: number\n45: lang?: string | undefined\n46: maxLines?: number | undefined\n47: className?: string | undefined\n48: }\n49: \n50: // A windowed read keeps the file line numbers in the gutter.\n51: const marker = \"fixture read sample\"\n\n(Showing lines 41-51 of 180. Use offset=52 to continue.)\n" - } - ], - "isError": false + "type": "text", + "text": "packages/client/ui-primitives/src/ReadBlock.tsx\nfile\n\n41: export interface ReadBlockProps {\n42: label?: string | undefined\n43: lines: readonly ReadBlockLine[]\n44: totalLines: number\n45: lang?: string | undefined\n46: maxLines?: number | undefined\n47: className?: string | undefined\n48: }\n49: \n50: // A windowed read keeps the file line numbers in the gutter.\n51: const marker = \"fixture read sample\"\n\n(Showing lines 41-51 of 180. Use offset=52 to continue.)\n" } ], - "role": "user", - "id": "937c02dd-63d8-4106-9310-a9df2055f0e9" + "isError": false }, "meta": { "path": "packages/client/ui-primitives/src/ReadBlock.tsx", @@ -4888,25 +4828,20 @@ "turn": 70, "step": 0, "message": { + "id": "c2ddb04d-74c9-4a2f-83f6-47a48fc6fbc2", + "role": "tool", + "toolCallId": "fx-call-70", "source": { "kind": "tool", "callId": "fx-call-70" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-70", - "content": [ - { - "type": "text", - "text": "Search results for deepseek harness architecture." - } - ], - "isError": false + "type": "text", + "text": "Search results for deepseek harness architecture." } ], - "role": "user", - "id": "c2ddb04d-74c9-4a2f-83f6-47a48fc6fbc2" + "isError": false }, "meta": { "answer": "DeepSeek Harness is a plugin-based agent harness on vendored Cordis where **every capability is a plugin**.", @@ -5113,25 +5048,20 @@ "turn": 71, "step": 0, "message": { + "id": "57cf5cd3-3daf-4e2c-bb16-f8695bc2ab8c", + "role": "tool", + "toolCallId": "fx-call-71", "source": { "kind": "tool", "callId": "fx-call-71" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-71", - "content": [ - { - "type": "text", - "text": "# Harness architecture\n\nEverything is a plugin." - } - ], - "isError": false + "type": "text", + "text": "# Harness architecture\n\nEverything is a plugin." } ], - "role": "user", - "id": "57cf5cd3-3daf-4e2c-bb16-f8695bc2ab8c" + "isError": false }, "meta": { "url": "https://www.deepseek.com/blog/harness-architecture", @@ -5702,25 +5632,20 @@ "turn": 74, "step": 0, "message": { + "id": "499968fd-a83f-45ad-80fe-b1d73651ff13", + "role": "tool", + "toolCallId": "fx-call-74", "source": { "kind": "tool", "callId": "fx-call-74" }, "content": [ { - "type": "tool-result", - "toolCallId": "fx-call-74", - "content": [ - { - "type": "text", - "text": "Updated todo list: 1 pending, 2 in progress, 1 completed." - } - ], - "isError": false + "type": "text", + "text": "Updated todo list: 1 pending, 2 in progress, 1 completed." } ], - "role": "user", - "id": "499968fd-a83f-45ad-80fe-b1d73651ff13" + "isError": false } } } diff --git a/apps/web/tests/fork-mid-turn.e2e.ts b/apps/web/tests/fork-mid-turn.e2e.ts new file mode 100644 index 0000000000..2ffa330007 --- /dev/null +++ b/apps/web/tests/fork-mid-turn.e2e.ts @@ -0,0 +1,191 @@ +// Web e2e: fork a completed recording at its first tool/call over HTTP, +// verify both synthetic result texts, and continue the child through the composer. +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' +import type { Browser, Page } from 'playwright' +import { chromium } from 'playwright' +import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' +import type { StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ReplayEntry } from '@deepseek-ai/dsh-llm-replay' +import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' +import { + assertFixtureInventory, captureStableAria, compareOrRefreshGolden, + launchWebScaffold, parseSeedFixture, seedSession, + watchConsole, webSnapshotMode, selectedSessionFixture, type WebScaffold, +} from './scaffold.ts' +import { newEnglishPage, saveFailureShot, writeComposerDraft } from './support.ts' + +const SNAPSHOT_DIR = fileURLToPath(new URL('./expected/fork-mid-turn', import.meta.url)) +// Borrowed read-only from its recorded-session owner. +const SEED = fileURLToPath(new URL('../../../snapshots/web/seeded-history/session.v3.jsonl', import.meta.url)) +const UI_EXPECTED = join(SNAPSHOT_DIR, 'ui.expected.md') +const MODE = webSnapshotMode() +const SEED_ID = 'fork-mid-turn-web-e2e' +const PROMPT = 'FORK_BRANCH_USER Summarize what this branch knows about the reads.' +const FIRST_MARKER = 'FORK_BRANCH_FIRST' +const DONE_MARKER = 'FORK_BRANCH_DONE' + +// The exact model-visible branch wordings (`openTurnClosers`, forked cause). +const OUTCOME_UNKNOWN_TEXT = 'The history inherited by this branch records this tool call starting but does not include its result. The parent session may have completed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.' +const NOT_STARTED_TEXT = 'The history inherited by this branch has no record of this tool call starting. The parent session may have executed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.' + +/** The child's one continuation stream, fully scripted (no recording). */ +function continuationScript(): ReplayEntry[] { + const deltas = [ + `${FIRST_MARKER} this branch has no read results, `, + `so I would check what the parent completed before retrying. ${DONE_MARKER}.`, + ] + const response = deltas.join('') + const chunks: StreamChunk[] = [ + { type: 'block-start', index: 0, blockType: 'text' }, + ...deltas.map(text => ({ type: 'text-delta' as const, index: 0, text })), + { type: 'block-end', index: 0, block: { type: 'text', text: response } }, + { type: 'usage', usage: { inputTokens: 512, outputTokens: 32 } }, + { type: 'finish', reason: { kind: 'stop' } }, + ] + return [{ kind: 'chunks', chunks }] +} + +function toolResultText(event: SessionEvent<'tool/result'>): string { + return event.data.message.content + .filter(block => block.type === 'text') + .map(block => block.text) + .join('') +} + +describe('web e2e: exact-boundary fork seeds branch closers and continues', () => { + let scaffold: WebScaffold + let browser: Browser + let page: Page + let replayDir: string + let tripwire: ReturnType + let childId: SessionId + let forkAt: number + + beforeAll(async () => { + replayDir = await mkdtemp(join(tmpdir(), 'dsh-fork-mid-turn-replay-')) + const replayOverride = join(replayDir, 'replay.override.json') + await writeFile(replayOverride, JSON.stringify(continuationScript())) + scaffold = await launchWebScaffold({ + replayFixture: join(replayDir, 'override-only.jsonl'), + replayOverride, + // Use paced chunks for the child continuation's live-stream assertions. + paceMs: 5, + }) + const fixture = await readFile(await selectedSessionFixture(SEED), 'utf8') + const firstCall = parseSeedFixture(fixture).events.find(event => event.type === 'tool/call') + if (firstCall === undefined) throw new Error('fork-mid-turn seed lacks a tool/call') + forkAt = firstCall.seq + await seedSession(scaffold, fixture, SEED_ID) + browser = await chromium.launch() + page = await newEnglishPage(browser) + tripwire = watchConsole(page) + await page.goto(scaffold.authenticatedUrl, { waitUntil: 'load' }) + await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) + }, 120_000) + + afterAll(async () => { + const failures: unknown[] = [] + await browser?.close().catch((error: unknown) => failures.push(error)) + await scaffold?.close().catch((error: unknown) => failures.push(error)) + if (replayDir !== undefined) { + await rm(replayDir, { recursive: true, force: true }) + .catch((error: unknown) => failures.push(error)) + } + if (failures.length === 1) throw failures[0] + if (failures.length > 1) throw new AggregateError(failures, 'fork-mid-turn e2e cleanup failed') + }) + + it.skipIf(MODE === 'record')('forks the cold source at its first tool/call and seeds forked closers', async () => { + const response = await scaffold.hostFetch('/api/session/fork', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ + type: 'client-request', rpcId: 'fork-mid-turn-exact', method: 'session/fork', + payload: { args: { request: { sessionId: SEED_ID, atSeq: forkAt } } }, + }), + }) + expect(response.ok).toBe(true) + const body = await response.json() as { result: { ok: boolean; value?: { sessionId: string } } } + expect(body.result.ok).toBe(true) + childId = SessionId(body.result.value!.sessionId) + + const child = scaffold.ctx.sessions.get(childId) + if (child === undefined) throw new Error('fork did not publish a live child session') + expect(child.header.parentSession).toBe(SessionId(SEED_ID)) + // inheritedEventCount counts only the copied parent prefix; the closers are child work. + expect(child.inheritedEventCount).toBe(forkAt + 1) + expect(child.snapshotEvents()[forkAt]?.type).toBe('tool/call') + + const closers = child.snapshotEvents().slice(forkAt + 1, forkAt + 6) + expect(closers.map(event => event.type)).toEqual([ + 'session/end-seed', 'tool/result', 'tool/result', 'step/end', 'turn/end', + ]) + const [, dispatched, notStarted, , turnEnd] = closers + expect(dispatched?.type === 'tool/result' && dispatched.data.error?.code).toBe('TOOL_OUTCOME_UNKNOWN') + expect(dispatched?.type === 'tool/result' && toolResultText(dispatched)).toBe(OUTCOME_UNKNOWN_TEXT) + expect(notStarted?.type === 'tool/result' && notStarted.data.error?.code).toBe('TOOL_NOT_STARTED') + expect(notStarted?.type === 'tool/result' && toolResultText(notStarted)).toBe(NOT_STARTED_TEXT) + expect(turnEnd?.type === 'turn/end' && turnEnd.data.reason).toEqual({ kind: 'forked' }) + }, 60_000) + + it.skipIf(MODE === 'record')('continues the child through the composer as a resume of the branched log', async () => { + onTestFailed(() => saveFailureShot(page, 'web-e2e-fork-mid-turn')) + // The session-added frame published the child row; the list sorts by + // recency, so the just-forked child is the first session row after the + // group header (the seeded source stays last). The settled-turn assertion + // below proves the prompt really ran on the child. + const groupRow = page.locator('[role="treeitem"]').first() + await groupRow.waitFor({ timeout: 15_000 }) + await groupRow.click() + await expect.poll(() => page.locator('[role="treeitem"]').count(), { timeout: 15_000 }).toBe(3) + await page.locator('[role="treeitem"]').nth(1).click() + // The child renders the inherited prefix up to the cut. + await expect.poll(() => page.getByText('Use the read tool twice', { exact: false }).count(), { timeout: 15_000 }) + .toBeGreaterThanOrEqual(1) + + const composer = page.locator('[data-composer-input]').last() + await composer.waitFor({ timeout: 15_000 }) + await writeComposerDraft(page, composer, PROMPT) + const settled = scaffold.whenTurnSettled(60_000) + await page.getByRole('button', { name: 'Send message', exact: true }).click() + await page.getByText(FIRST_MARKER, { exact: false }).last().waitFor({ timeout: 15_000 }) + expect(await settled).toBe(childId) + await page.getByText(`${DONE_MARKER}.`, { exact: false }).last().waitFor({ timeout: 15_000 }) + await expect.poll(() => page.locator('[data-streaming="true"]').count(), { timeout: 15_000 }).toBe(0) + + // The branch continuation is a resume over the seeded log: the synthetic + // closer ended turn 1, so the live turn is 2, and its first request logs + // a resume header rather than a fresh conversation header. + const child = scaffold.ctx.sessions.get(childId) + if (child === undefined) throw new Error('child session disappeared after its turn') + const live = child.snapshotEvents().filter(event => event.seq >= child.firstLiveSeq) + expect(live.filter(event => event.type === 'turn/start').map(event => event.data.turn)).toEqual([2]) + expect(live.filter(event => event.type === 'request/header').map(event => event.data.reason)).toEqual(['resume']) + const reply = child.deriveMessages().at(-1) + expect(reply?.role).toBe('assistant') + expect(JSON.stringify(reply?.content)).toContain(DONE_MARKER) + }, 60_000) + + it.skipIf(MODE === 'record')('matches the child conversation-flow aria golden', async () => { + onTestFailed(() => saveFailureShot(page, 'web-e2e-fork-mid-turn-aria')) + await page.getByText(`${DONE_MARKER}.`, { exact: false }).last().waitFor({ timeout: 10_000 }) + const flow = page.locator('[data-chat-flow]') + const branchAction = flow.locator('[data-turn-tail="2"]').getByRole('button', { + name: 'Branch into a new conversation', exact: true, + }) + await branchAction.waitFor({ timeout: 10_000 }) + expect(await branchAction.isEnabled()).toBe(true) + const snapshot = (await captureStableAria(page, '[data-chat-flow]', scaffold.workspaceCwd)) + .split(SEED_ID).join('{{seededId}}') + await compareOrRefreshGolden(UI_EXPECTED, snapshot, MODE) + }) + + it.skipIf(MODE === 'record')('kept the console clean and the fixture inventory closed', async () => { + expect(tripwire.pageErrors).toEqual([]) + expect(tripwire.warnings).toEqual([]) + await assertFixtureInventory(SNAPSHOT_DIR, ['ui.expected.md']) + }) +}) diff --git a/apps/web/tests/github-ready-review.e2e.ts b/apps/web/tests/github-ready-review.e2e.ts index 54a0e604c1..1477e2ea25 100644 --- a/apps/web/tests/github-ready-review.e2e.ts +++ b/apps/web/tests/github-ready-review.e2e.ts @@ -179,7 +179,7 @@ describe.skipIf(MODE === 'record')('web e2e: GitHub ready-for-review', () => { expect(agent).toBeDefined() const workspace = await scaffold.ctx.workspaceRegistry.resolveByPath(scaffold.workspaceCwd) expect(workspace?.sessionIds).toContain(agent?.id) - const webhookMessage = adapter.requests[0]?.messages.find(message => message.source.kind === 'webhook') + const webhookMessage = adapter.requests[0]?.messages.find(message => message.role === 'user' && message.source?.kind === 'webhook') expect(webhookMessage?.content).toHaveLength(1) const [content] = webhookMessage?.content ?? [] expect(content?.type).toBe('text') diff --git a/apps/web/tests/minimal-preset.snapshot.ts b/apps/web/tests/minimal-preset.snapshot.ts index 22ab1bc476..1c41897422 100644 --- a/apps/web/tests/minimal-preset.snapshot.ts +++ b/apps/web/tests/minimal-preset.snapshot.ts @@ -82,8 +82,7 @@ describe('minimal agent preset', () => { const systemPrompt = systemPromptText(agentHandle.agent.session) if (systemPrompt === undefined) throw new Error('the minimal agent issued no system prompt') expect(agentHandle.agent.session.snapshotEvents().some(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt')).toBe(false) + && event.data.source.kind === 'runtime-context')).toBe(false) expect(scaffold.ctx.agentPresets.serviceFor(agentHandle.agent, 'fs')).toBeUndefined() expect(scaffold.ctx.agentPresets.serviceFor(agentHandle.agent, 'compaction')).toBeUndefined() diff --git a/apps/web/tests/permission-policy-context.e2e.ts b/apps/web/tests/permission-policy-context.e2e.ts index e946968359..c57ee84667 100644 --- a/apps/web/tests/permission-policy-context.e2e.ts +++ b/apps/web/tests/permission-policy-context.e2e.ts @@ -43,8 +43,7 @@ function systemPrompts(events: readonly SessionEvent[]): string[] { function runtimeContexts(events: readonly SessionEvent[]): string[] { return events.flatMap((event) => { if (event.type !== 'user/message' - || event.data.source.kind !== 'plugin' - || event.data.source.plugin !== '@deepseek-ai/dsh-system-prompt') return [] + || event.data.source.kind !== 'runtime-context') return [] return event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) }) } diff --git a/apps/web/tests/plan-review.e2e.ts b/apps/web/tests/plan-review.e2e.ts index 1e1a94c1f4..5362264b42 100644 --- a/apps/web/tests/plan-review.e2e.ts +++ b/apps/web/tests/plan-review.e2e.ts @@ -248,7 +248,7 @@ describe('web e2e: dismissed plan history', () => { expect(call).toBeDefined() const results = events.filter(event => event.type === 'tool/result') const result = results.find(event => event.data.message.source.callId === call?.data.callId) - expect(result?.data.message.content[0]).toMatchObject({ type: 'tool-result', isError: true }) + expect(result?.data.message).toMatchObject({ role: 'tool', toolCallId: call?.data.callId, isError: true }) expect(JSON.stringify(result)).toContain('dismissed the plan review') expect(results.some(event => JSON.stringify(event).includes('Plan approved'))).toBe(false) const modes = events.filter(event => event.type === 'plan/mode') diff --git a/apps/web/tests/present.e2e.ts b/apps/web/tests/present.e2e.ts index bf8eb5e1e8..1c4c5fe44f 100644 --- a/apps/web/tests/present.e2e.ts +++ b/apps/web/tests/present.e2e.ts @@ -106,7 +106,7 @@ fs.appendFileSync(${JSON.stringify(openLog)}, JSON.stringify({ path, action, con } } expect(events.some(event => event.type === 'tool/ptc-dispatch' && event.data.name === 'present' && event.data.isError)).toBe(true) - expect(events.some(event => event.type === 'tool/result' && event.data.message.content[0].isError)).toBe(true) + expect(events.some(event => event.type === 'tool/result' && event.data.message.isError)).toBe(true) }, 200_000) it('opens current source files after edits and reload, and reports deletion without downloading', async () => { diff --git a/apps/web/tests/preset-migration.snapshot.ts b/apps/web/tests/preset-migration.snapshot.ts index 7fb3d881d2..d8fccb3271 100644 --- a/apps/web/tests/preset-migration.snapshot.ts +++ b/apps/web/tests/preset-migration.snapshot.ts @@ -1,11 +1,11 @@ -/** Cold V2 restoration mounts the shipped PTC preset and publishes only a V3 successor. */ +/** Cold V2 restoration mounts the shipped PTC preset and publishes only the current successor. */ import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises' -import { dirname, join } from 'node:path' +import { dirname } from 'node:path' import { fileURLToPath } from 'node:url' import { zstdCompressSync, zstdDecompressSync } from 'node:zlib' import { describe, expect, it } from 'vitest' -import { SessionId } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' import { generationLogPath } from '../../../packages/session/session-persistence-jsonl/src/format.ts' import { scanZstdFrames } from '../../../packages/session/session-persistence-jsonl/src/zstd.ts' import type {} from '@deepseek-ai/dsh-agent-presets' @@ -28,7 +28,7 @@ describe.skipIf(webSnapshotMode() === 'record')('historical preset restoration t const rows: Record[] = events.map((event, seq) => ({ ...event, seq, time: seq + 2 })) const source = Buffer.concat([header, ...rows].map(row => zstdCompressSync(Buffer.from(JSON.stringify(row) + '\n')))) const predecessor = generationLogPath(scaffold.persistenceRoot, scaffold.workspaceCwd, id, 2, 'zstd') - const successor = join(dirname(predecessor), 'session.v3.jsonl.zstd') + const successor = generationLogPath(scaffold.persistenceRoot, scaffold.workspaceCwd, id, SESSION_FORMAT_VERSION, 'zstd') await mkdir(dirname(predecessor), { recursive: true }) await writeFile(predecessor, source) @@ -53,7 +53,7 @@ describe.skipIf(webSnapshotMode() === 'record')('historical preset restoration t const published = Buffer.concat(scanZstdFrames(publishedBytes).frames .map(({ start, end }) => zstdDecompressSync(publishedBytes.subarray(start, end)))).toString('utf8') const expected = [ - { ...header, version: 3, agentPreset: 'ptc' }, + { ...header, version: SESSION_FORMAT_VERSION, agentPreset: 'ptc' }, ...rows.map(row => row['type'] === 'agent-preset/selected' && (row['data'] as { agentPreset: string }).agentPreset === 'code' ? { ...row, data: { agentPreset: 'ptc' } } @@ -65,7 +65,7 @@ describe.skipIf(webSnapshotMode() === 'record')('historical preset restoration t expect(normalizeSessionSnapshots([published], context)).toEqual(normalizeSessionSnapshots([expected], context)) expect(await readFile(predecessor)).toEqual(source) expect((await readdir(dirname(predecessor))).filter(name => name.endsWith('.jsonl.zstd')).sort()) - .toEqual(['session.v2.jsonl.zstd', 'session.v3.jsonl.zstd']) + .toEqual(['session.v2.jsonl.zstd', `session.v${SESSION_FORMAT_VERSION}.jsonl.zstd`]) } finally { await scaffold.close() } diff --git a/apps/web/tests/preview-boot.e2e.ts b/apps/web/tests/preview-boot.e2e.ts index f27edc18d8..bde54fe69e 100644 --- a/apps/web/tests/preview-boot.e2e.ts +++ b/apps/web/tests/preview-boot.e2e.ts @@ -28,7 +28,7 @@ import { chromium } from 'playwright' import type { Browser } from 'playwright' import { expect, it } from 'vitest' import { - composeProfile, configTrees, indexWorkspacePackages, packVfsImage, packVfsOverlay, + composeProfile, configTrees, indexWorkspacePackages, packVfsImage, packPreviewFixture, previewFixtures, WRAPPER_CONTRACT, } from '@deepseek-ai/dsh-experimental-webworker-packer' import { @@ -119,9 +119,9 @@ function requirePreviewPages(): void { * The base image, fixture manifest, and overlays to serve. `pnpm run build` * emits the pages but only `build:preview` packs the image, so this lane packs * a missing image rather than skipping the deployment it accepts. The example - * overlay pairs its committed Session generations with the generator-owned - * current projection cache. The worker therefore exercises historical reads - * without relying on a stale cache schema. Generated files land in a temp + * overlay retains its committed Session generations, prepares current successors + * through the Node catalog, and supplies the generator-owned current projection cache. + * Generated files land in a temp * directory, never in `dist/`: the * client-artifact digest record treats `dist/` as build-owned, so a test write * there fails the record check for every later consumer. @@ -162,7 +162,7 @@ function requireVfsAssets(): PreviewAssets { const trees = fixture.id === 'vfs-example' ? [...fixture.trees, { mount: 'home/storages', directory: cacheDirectory }] : fixture.trees - writeAsset(relativePath, packVfsOverlay(trees).image) + writeAsset(relativePath, packPreviewFixture(trees).image) return { id: fixture.id, label: fixture.label, diff --git a/apps/web/tests/question-composer.e2e.ts b/apps/web/tests/question-composer.e2e.ts index 260792f545..1f10a588b5 100644 --- a/apps/web/tests/question-composer.e2e.ts +++ b/apps/web/tests/question-composer.e2e.ts @@ -280,11 +280,10 @@ describe('web e2e: resident question composer round trip', () => { answeredSession = sessionId // World state: the tool result carries the chosen answer, and DONE lands. const results = sessionEvents.filter(e => e.type === 'tool/result') - const answerText = results.flatMap(event => event.data.message.content.flatMap(block => - block.type === 'tool-result' - ? block.content.filter(item => item.type === 'text').map(item => item.text) - : [], - )).at(-1) + const answerText = results.flatMap(event => event.data.message.content + .filter(item => item.type === 'text') + .map(item => item.text), + ).at(-1) expect(JSON.parse(answerText ?? '')).toEqual({ answers: [{ id: 'color', selected: ['Blue'], custom: 'Include accessibility notes' }], }) diff --git a/apps/web/tests/replay-round-trip.e2e.ts b/apps/web/tests/replay-round-trip.e2e.ts index b4e78ec07e..8bddaee2d7 100644 --- a/apps/web/tests/replay-round-trip.e2e.ts +++ b/apps/web/tests/replay-round-trip.e2e.ts @@ -171,8 +171,8 @@ describe('web e2e: fresh round trip through the real assembly', () => { const bashResult = sessionEvents.find(event => event.type === 'tool/result' && event.data.message.source.callId === bashCall.data.callId) if (bashResult?.type !== 'tool/result') throw new Error('the bash tool call produced no durable result') - expect(bashResult.data.message.content[0].isError).toBe(false) - expect(bashResult.data.message.content[0].content.filter(block => block.type === 'text').map(block => block.text).join('')) + expect(bashResult.data.message.isError).toBe(false) + expect(bashResult.data.message.content.filter(block => block.type === 'text').map(block => block.text).join('')) .toBe('WEB_E2E_OK\n') const turnEnds = sessionEvents.filter(e => e.type === 'turn/end') expect(turnEnds.length).toBe(1) diff --git a/apps/web/tests/scaffold-generation.spec.ts b/apps/web/tests/scaffold-generation.spec.ts index 198268c9f1..f6d735b1d8 100644 --- a/apps/web/tests/scaffold-generation.spec.ts +++ b/apps/web/tests/scaffold-generation.spec.ts @@ -1,9 +1,11 @@ import { afterEach, describe, expect, it } from 'vitest' -import { mkdtemp, rm, writeFile } from 'node:fs/promises' +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' +import { parseSessionLog, prepareSessionSnapshotFixtureForComparison } from '@deepseek-ai/dsh-llm-replay' import { assertFixtureInventory, + parseSeedFixture, recordedSessionFixturePath, selectedSessionFixture, } from './scaffold.ts' @@ -14,6 +16,33 @@ afterEach(async () => { for (const root of roots.splice(0)) await rm(root, { recursive: true, force: true }) }) +describe('Web seed stream timing', () => { + it.each([2, 3])('preserves embedded timestamps from format v%i and its current projection', async (version) => { + const fixture = await readFile(new URL(`../../../snapshots/session/skill-load/session.v${version}.jsonl`, import.meta.url), 'utf8') + const current = prepareSessionSnapshotFixtureForComparison(fixture) + const expected = parseSessionLog(current) + + expect(parseSeedFixture(fixture).events).toEqual(expected) + expect(parseSeedFixture(current).events).toEqual(expected) + }) + + it.each(['session.jsonl', 'session.v1.jsonl'])('reconstructs positive stream intervals from %s', async (filename) => { + const fixture = await readFile(new URL(`../../../snapshots/session/text-turn/${filename}`, import.meta.url), 'utf8') + const messages = parseSeedFixture(fixture).events.filter(event => event.type === 'assistant/message') + expect(messages).toHaveLength(1) + const stream = messages[0]!.data.stream + expect(stream.length).toBeGreaterThan(1) + + let previousEnd = -1 + for (const record of stream) { + const start = 'time' in record ? record.time : record.time0 + expect(start).toBeGreaterThan(previousEnd) + previousEnd = 'time' in record ? record.time : record.time0 + record.dt.reduce((total, delta) => total + delta, 0) + } + expect(previousEnd).toBeGreaterThan(0) + }) +}) + describe('Web snapshot generation filenames', () => { it('selects the highest parent and child generations without counting retained inputs twice', async () => { const root = await mkdtemp(join(tmpdir(), 'dsh-web-fixture-generations-')) diff --git a/apps/web/tests/scaffold.ts b/apps/web/tests/scaffold.ts index 924afc8d7b..e7249a0b67 100644 --- a/apps/web/tests/scaffold.ts +++ b/apps/web/tests/scaffold.ts @@ -1301,12 +1301,7 @@ export function realizeSeedFixture(scaffold: WebScaffold, fixtureText: string, i }).join('\n') } -/** - * Parse a committed web seed fixture through the replay reader. - * @param fixtureText - session JSONL fixture contents. - * @returns the current header line, parsed header, and logical events. - */ -/** Give a migrated fixture stream positive relative timing before its final wall-clock rebase. */ +/** Give reconstructed V0/V1 chunk streams positive intervals before the final wall-clock rebase. */ function spreadMigratedSeedStream( stream: SessionEvent<'assistant/message'>['data']['stream'], ): SessionEvent<'assistant/message'>['data']['stream'] { @@ -1323,6 +1318,12 @@ function spreadMigratedSeedStream( }) } +/** + * Parse a committed web seed fixture through the replay reader. + * Embedded streams retain their recorded timing; V0/V1 chunk streams receive positive relative intervals. + * @param fixtureText - session JSONL fixture contents. + * @returns the current header line, parsed header, and logical events. + */ export function parseSeedFixture(fixtureText: string): { headerLine: string header: Record @@ -1337,7 +1338,7 @@ export function parseSeedFixture(fixtureText: string): { const header = JSON.parse(headerLine) as Record if (header.type !== 'session') throw new Error('seed fixture must start with a session header') const events = parseSessionLog(current).map((event) => { - if (sourceHeader.version === SESSION_FORMAT_VERSION) return event + if (sourceHeader.version !== 0 && sourceHeader.version !== 1) return event if (event.type === 'assistant/message') { return { ...event, data: { ...event.data, stream: spreadMigratedSeedStream(event.data.stream) } } } diff --git a/apps/web/tests/schedule-after.e2e.ts b/apps/web/tests/schedule-after.e2e.ts index 6a36d256ea..fd2a0369fa 100644 --- a/apps/web/tests/schedule-after.e2e.ts +++ b/apps/web/tests/schedule-after.e2e.ts @@ -9,7 +9,7 @@ import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' import type { Agent, AgentHandle } from '@deepseek-ai/dsh-agent' import { composeEntries, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' import { ToolCallId, createUserMessage, LlmAdapter } from '@deepseek-ai/dsh-llm' -import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed, GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import { ScheduleId, @@ -35,6 +35,12 @@ import { saveFailureShot, } from './support.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'schedule-web-e2e': { kind: 'schedule-web-e2e' } & ContextFormed + } +} + const MODE = webSnapshotMode() const OVERLAY = fileURLToPath(new URL('../../cli/config/examples/schedule/cordis.yml', import.meta.url)) const SNAPSHOT_DIR = fileURLToPath(new URL('./expected/schedule-after', import.meta.url)) @@ -190,7 +196,7 @@ function requestText(options: GenerateOptions): string { /** Require one assembled request to preserve the reminder-content trust boundary. */ function expectReminderFraming(options: GenerateOptions): void { const reminder = options.messages.find(message => ( - message.source.kind === 'plugin' && message.source.plugin === 'schedule' + message.role === 'user' && message.source?.kind === 'schedule' )) expect(reminder?.role).toBe('user') const text = reminder?.content.find(block => block.type === 'text')?.text @@ -389,7 +395,7 @@ describe.skipIf(MODE === 'record')('web e2e: conversational reminders', () => { }) atHandle.agent.followup(createUserMessage({ content: [{ type: 'text', text: 'Prepare the reminder test session.' }], - source: { kind: 'plugin', plugin: 'schedule-web-e2e' }, + source: { kind: 'schedule-web-e2e' }, })) await atHandle.agent.whenIdle() expect(atAdapter.requests).toHaveLength(1) @@ -473,8 +479,7 @@ describe.skipIf(MODE === 'record')('web e2e: conversational reminders', () => { const batch = everyHandle.agent.session.snapshotEvents().find(event => ( event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === 'schedule' + && event.data.source.kind === 'schedule' && event.data.content.some(block => block.type === 'text' && block.text.startsWith('[SCHEDULE REMINDER BATCH]')) )) diff --git a/apps/web/tests/seeded-history.e2e.ts b/apps/web/tests/seeded-history.e2e.ts index 3fc30d72ba..b31b33bba0 100644 --- a/apps/web/tests/seeded-history.e2e.ts +++ b/apps/web/tests/seeded-history.e2e.ts @@ -17,7 +17,7 @@ import { chromium } from 'playwright' import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' import { createLaunchEnvironmentSnapshot } from '@deepseek-ai/dsh-launch-environment' import { createUserMessage } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, Message } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, ContextFormed, Message, MessageSource } from '@deepseek-ai/dsh-llm' import { deriveEventMessage, SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import type { TokenMeter } from '@deepseek-ai/dsh-token-meter' @@ -31,6 +31,15 @@ import { } from './scaffold.ts' import { expandOwningTurnProcess, newEnglishPage, saveFailureShot } from './support.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'fixture': { kind: 'fixture' } & ContextFormed + } +} + +type CheckpointSource = Extract +type CheckpointCommandId = NonNullable + const SNAPSHOT_DIR = fileURLToPath(new URL('../../../snapshots/web/seeded-history', import.meta.url)) const SEED = fileURLToPath(new URL('../../../snapshots/web/seeded-history/session.v3.jsonl', import.meta.url)) const UI_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/seeded-history/ui.expected.md', import.meta.url)) @@ -105,8 +114,8 @@ function withCompaction(raw: string, meter: TokenMeter): string { events.push({ ...event, seq: taken, time: time++ }) return taken } - const commandId = 'cmd-seeded-manual-compact' - const compactionId = 'compact-seeded-manual-compact' + const commandId = 'cmd-seeded-manual-compact' as CheckpointCommandId + const compactionId = 'compact-seeded-manual-compact' as CheckpointSource['compactionId'] at({ type: 'command/run', data: { commandId, name: 'compact', args: '', source: { kind: 'user' } }, @@ -173,7 +182,7 @@ function withCompaction(raw: string, meter: TokenMeter): string { text: 'Model-only compact checkpoint.', }], source: { - kind: 'plugin', plugin: 'compact', compactionId, sourceCommandId: commandId, + kind: 'compact-checkpoint', compactionId, sourceCommandId: commandId, }, }), surfaceOp: { op: 'replace', startSeq: first, endSeq: last }, @@ -781,7 +790,7 @@ describe('web e2e: seeded history renders through cold resume', () => { if (agent === undefined) throw new Error('seeded session did not attach an agent') agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'Short injected context.' }], - source: { kind: 'plugin', plugin: 'fixture' }, + source: { kind: 'fixture' }, }), { surfaceOp: 'append' }) const disclosure = page.getByRole('button', { name: 'Context injection fixture', exact: true }) diff --git a/apps/web/tests/shipped-composition.e2e.ts b/apps/web/tests/shipped-composition.e2e.ts index 9372b32e61..a6656d2ff5 100644 --- a/apps/web/tests/shipped-composition.e2e.ts +++ b/apps/web/tests/shipped-composition.e2e.ts @@ -45,6 +45,18 @@ const AUTO_PARENT_ONE_SHOT = 'AUTO_PARENT_ONE_SHOT' const AUTO_PARENT_CONTINUABLE = 'AUTO_PARENT_CONTINUABLE' const AUTO_PARENT_ADJUST = 'AUTO_PARENT_ADJUST' +/** Identify the one-shot Auto Review request and check its request-only outer input. */ +function isAutoReviewRequest(options: GenerateOptions): boolean { + if (options.system?.startsWith('REVIEW_POLICY\n') !== true) return false + expect(options.messages).toHaveLength(1) + const message = options.messages[0] + expect(message).toMatchObject({ role: 'user', content: [{ type: 'text' }] }) + expect(message?.content).toHaveLength(1) + expect(message).not.toHaveProperty('id') + expect(message).not.toHaveProperty('source') + return true +} + type RpcResult = { ok: true; value: T } | { ok: false; error: { code: string; message: string } } /** POST one generated Remote unary through the authenticated Web carrier. */ @@ -94,14 +106,13 @@ class ShippedAutoAdapter extends LlmAdapter { override async *stream(options: GenerateOptions): AsyncIterable { this.requests.push(options) - const source = options.messages[0]?.source - if (source?.kind === 'plugin' && source.plugin === 'dsh-experimental-auto-review') { + if (isAutoReviewRequest(options)) { yield* textChunks(JSON.stringify({ risk: 'medium', decision: 'deny', reason: AUTO_RAW_REASON, })) return } - if (options.messages.some(message => message.content.some(block => block.type === 'tool-result'))) { + if (options.messages.some(message => message.role === 'tool')) { yield* textChunks(AUTO_FINAL_TEXT) return } @@ -214,8 +225,7 @@ class ShippedChildAutoAdapter extends LlmAdapter { override async *stream(options: GenerateOptions): AsyncIterable { this.requests.push(options) - const source = options.messages[0]?.source - const response = source?.kind === 'plugin' && source.plugin === 'dsh-experimental-auto-review' + const response = isAutoReviewRequest(options) ? this.reviewResponse(options) : this.mainResponse(options) yield* response @@ -429,10 +439,9 @@ function toolOutcomes(events: readonly SessionEvent[]): Array<{ name: string; co } return events.flatMap((event) => { if (event.type !== 'tool/result') return [] - const block = event.data.message.content.find(item => item.type === 'tool-result') - if (block === undefined) return [] - const name = names.get(block.toolCallId) - if (name === undefined) throw new Error(`tool result ${block.toolCallId} has no matching call`) + const { toolCallId } = event.data.message + const name = names.get(toolCallId) + if (name === undefined) throw new Error(`tool result ${toolCallId} has no matching call`) return [{ name, ...event.data.error === undefined ? {} : { code: event.data.error.code } }] }) } @@ -792,7 +801,7 @@ it('routes one browser-authored Auto request through the same model before a rea expect(prompt).toBeDefined() const result = events.find((event): event is Extract => ( event.type === 'tool/result' - && event.data.message.content.some(block => block.toolCallId === AUTO_CALL_ID) + && event.data.message.toolCallId === AUTO_CALL_ID )) expect(result?.data.error).toEqual({ name: 'AutoReviewDeniedError', diff --git a/apps/web/tests/sidebar-right.e2e.ts b/apps/web/tests/sidebar-right.e2e.ts index 85b878c7a3..ffcc3c42a7 100644 --- a/apps/web/tests/sidebar-right.e2e.ts +++ b/apps/web/tests/sidebar-right.e2e.ts @@ -297,9 +297,11 @@ describe('web e2e: shipped right Sidebar', () => { step: 1, message: { id: 'result-call-write-1', - role: 'user', + role: 'tool', source: { kind: 'tool', callId: 'call-write-1' }, - content: [{ type: 'tool-result', toolCallId: 'call-write-1', content: [{ type: 'text', text: 'ok' }] }], + toolCallId: 'call-write-1', + content: [{ type: 'text', text: 'ok' }], + isError: false, }, } as never, { surfaceOp: 'append' }) agent.session.append('assistant/message', { diff --git a/apps/web/tests/snapshots/streaming-fence-highlight/mid-stream.expected.md b/apps/web/tests/snapshots/streaming-fence-highlight/mid-stream.expected.md index 5a4c4fce85..27e4c283ae 100644 --- a/apps/web/tests/snapshots/streaming-fence-highlight/mid-stream.expected.md +++ b/apps/web/tests/snapshots/streaming-fence-highlight/mid-stream.expected.md @@ -9,7 +9,7 @@ - button "System prompt" - text: Stream one TypeScript fence for the highlighting snapshot. {{clock}} - button "Copy" -- button "Context injection @deepseek-ai/dsh-system-prompt" +- button "Context injection runtime-context" - text: ts - button "Copy" - code: "const first: number = 1 const second = \"two\" let tail" diff --git a/apps/web/tests/stats-paged-history.e2e.ts b/apps/web/tests/stats-paged-history.e2e.ts index 6fc50a5e2b..5531a4dbda 100644 --- a/apps/web/tests/stats-paged-history.e2e.ts +++ b/apps/web/tests/stats-paged-history.e2e.ts @@ -50,7 +50,7 @@ function buildSeed(turns: number): string { if (turn === 1) { at({ type: 'system/message', - data: { turn, step: 1, message: createSystemMessage('', '@deepseek-ai/dsh-system-prompt') }, + data: { turn, step: 1, message: createSystemMessage('') }, surfaceOp: 'append', }) } diff --git a/apps/web/tests/subagent-conversation.e2e.ts b/apps/web/tests/subagent-conversation.e2e.ts index 76c752cd02..3fc4841f43 100644 --- a/apps/web/tests/subagent-conversation.e2e.ts +++ b/apps/web/tests/subagent-conversation.e2e.ts @@ -7,7 +7,8 @@ import { chromium } from 'playwright' import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' import { prepareSessionSnapshotFixtureForComparison } from '@deepseek-ai/dsh-llm-replay' import { - SESSION_FORMAT_VERSION, SessionId as sessionId, SessionLogOffset, type SessionEvent, type SessionHeader, type SessionId, + SESSION_FORMAT_VERSION, SessionId as sessionId, SessionLogOffset, SessionSeq, + type SessionEvent, type SessionHeader, type SessionId, } from '@deepseek-ai/dsh-session' import type {} from '@deepseek-ai/dsh-agent' import { snapshotSubagentDescriptor } from '@deepseek-ai/dsh-subagent' @@ -24,9 +25,9 @@ const AVAILABLE_CHILD_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/s const AVAILABLE_CHILD_EXPANDED_EXPECTED = fileURLToPath( new URL('../../../snapshots/web/subagent-conversation/ui-expanded.expected.md', import.meta.url), ) +const CATALOG_PUSH_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/catalog-push.expected.md', import.meta.url)) const TREE_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/tree.expected.md', import.meta.url)) const BRANCHLESS_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/branchless.expected.md', import.meta.url)) -const STALE_CATALOG_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/stale-catalog.expected.md', import.meta.url)) const SIDEBAR_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/sidebar.expected.md', import.meta.url)) const SIDEBAR_CHAT_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/sidebar-chat.expected.md', import.meta.url)) const UNAVAILABLE_GRANDCHILD_EXPECTED = fileURLToPath(new URL('../../../snapshots/web/subagent-conversation/nested.expected.md', import.meta.url)) @@ -207,6 +208,19 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await oneShotHandle.close() scaffold.ctx.sessionProjectionCache.coldSnapshot(oneShotHeader, SessionLogOffset(0), oneShotEvents) await waitForCacheRow(scaffold, oneShotHeader) + await page.getByRole('button', { name: '1 subagent', exact: true }).waitFor({ timeout: 15_000 }) + const catalogReads = apiCalls.filter(path => path === '/api/session/projections').length + parent.session.append('subagent/catalog', { + version: 0, + childId: oneShotId, + childCreatedAt: oneShotAt, + mode: 'one-shot', + label: ONE_SHOT_LABEL, + }) + const pushedCount = page.getByRole('button', { name: '2 subagents', exact: true }) + await pushedCount.waitFor({ timeout: 15_000 }) + expect(apiCalls.filter(path => path === '/api/session/projections')).toHaveLength(catalogReads) + await compareOrRefreshGolden(CATALOG_PUSH_EXPECTED, await pushedCount.ariaSnapshot(), MODE) grandchildId = sessionId('recorded-grandchild') const authoredAt = Date.now() const grandchildHeader: SessionHeader = { @@ -258,38 +272,65 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await grandchildHandle.close() scaffold.ctx.sessionProjectionCache.coldSnapshot(grandchildHeader, SessionLogOffset(0), grandchildEvents) await waitForCacheRow(scaffold, grandchildHeader) + const childHandle = await scaffold.ctx.sessionPersistence.open(childId, 'write') + const childHeader = childHandle.header + const childInheritedEventCount = childHandle.inheritedEventCount + const { events: childEvents } = await childHandle.read() + const grandchildCatalogEvent: SessionEvent<'subagent/catalog'> = { + type: 'subagent/catalog', + seq: SessionSeq((childEvents.at(-1)?.seq ?? -1) + 1), + time: authoredAt, + data: { + version: 0, + childId: grandchildId, + childCreatedAt: authoredAt, + mode: 'continuable', + label: NESTED_LABEL, + }, + } + await childHandle.append([grandchildCatalogEvent]) + await childHandle.close() + scaffold.ctx.sessionProjectionCache.coldSnapshot( + childHeader, + childInheritedEventCount, + [...childEvents, grandchildCatalogEvent], + ) expect(scaffold.ctx.agents.get(childId)).toBeUndefined() expect(scaffold.ctx.agents.get(oneShotId)).toBeUndefined() expect(scaffold.ctx.agents.get(grandchildId)).toBeUndefined() - await expect(scaffold.ctx.subagents.listChildren(parent.id)).resolves.toMatchObject([ + expect(await scaffold.ctx.subagents.listChildren(parent.id)).toMatchObject([ { - kind: 'child', id: oneShotId, mode: 'one-shot', - label: ONE_SHOT_LABEL, activity: 'inactive', hasChildren: false, + id: childId, mode: 'continuable', label: LABEL, }, { - kind: 'child', id: childId, mode: 'continuable', label: LABEL, - activity: 'inactive', hasChildren: true, - }, - ]) - await expect(scaffold.ctx.subagents.listChildren(childId)).resolves.toMatchObject([ - { - kind: 'child', id: grandchildId, mode: 'continuable', - label: NESTED_LABEL, activity: 'inactive', hasChildren: false, + id: oneShotId, mode: 'one-shot', label: ONE_SHOT_LABEL, }, ]) + { + using observed = await scaffold.ctx.sessionQuery.observeSession(childId) + expect(observed.source).toBe('prepared') + expect(observed.projections?.values.subagentCatalog).toEqual([ + { id: grandchildId, createdAt: authoredAt, mode: 'continuable', label: NESTED_LABEL }, + ]) + expect(await scaffold.ctx.subagents.listChildren(childId)).toMatchObject([ + { + id: grandchildId, mode: 'continuable', label: NESTED_LABEL, + }, + ]) + } // These two cold fixtures were authored after the page's initial // session.list and intentionally emitted no api-session/added event. Reload // to exercise the restart baseline that discovers their full lineage. const warningStart = tripwire.warnings.length await page.reload({ waitUntil: 'load' }) await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) - const catalogButton = page.getByRole('button', { name: '3 subagents', exact: true }) + const catalogButton = page.getByRole('button', { name: '2 subagents', exact: true }) await catalogButton.waitFor({ timeout: 15_000 }) await catalogButton.hover() const catalogTree = page.getByRole('tree', { name: 'Subagent sessions' }) await catalogTree.getByRole('treeitem').nth(1).waitFor({ timeout: 15_000 }) await catalogTree.press('Escape') - await page.getByRole('button', { name: '3 subagents' }).waitFor({ timeout: 15_000 }) + await page.getByRole('button', { name: '2 subagents' }).waitFor({ timeout: 15_000 }) acknowledgeReloadConnectionLoss(tripwire, warningStart) }, 120_000) @@ -319,71 +360,19 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await writeComposerDraft(page, input, '') }) - it('keeps known descendants reachable across a stale empty catalog response', async () => { - onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-stale-catalog')) - const pattern = '**/api/subagents/list' - let firstClaimed = false - let emptyDelivered = false - let trailingRequested = false - let releaseCatalog = (): void => {} - const catalogHeld = new Promise((resolve) => { releaseCatalog = resolve }) - await page.route(pattern, async (route) => { - if (firstClaimed) { - const response = await route.fetch() - trailingRequested = true - await catalogHeld - await route.fulfill({ response }) - return - } - firstClaimed = true - const response = await route.fetch() - const body = await response.json() as { - result: { ok: true; value: { entries: unknown[] } } | { ok: false } - } - if (body.result.ok) body.result.value.entries = [] - await route.fulfill({ response, json: body }) - emptyDelivered = true - }) - - const warningStart = tripwire.warnings.length - try { - await page.reload({ waitUntil: 'load' }) - await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) - await expect.poll(() => emptyDelivered, { timeout: 15_000 }).toBe(true) - await page.getByRole('button', { name: '3 subagents' }).waitFor({ timeout: 15_000 }) - acknowledgeReloadConnectionLoss(tripwire, warningStart) - - await page.getByRole('button', { name: '3 subagents' }).hover() - await expect.poll(() => trailingRequested, { timeout: 15_000 }).toBe(true) - const tree = page.getByRole('tree', { name: 'Subagent sessions' }) - await tree.getByRole('treeitem', { name: 'Loading subagents' }).first().waitFor() - expect(await tree.getByRole('treeitem', { name: 'Loading subagents' }).count()).toBe(2) - await compareOrRefreshGolden( - STALE_CATALOG_EXPECTED, - await captureStableAria(page, '[role="tree"][aria-label="Subagent sessions"]', scaffold.workspaceCwd), - MODE, - ) - releaseCatalog() - await tree.getByRole('treeitem', { name: new RegExp(LABEL) }).waitFor({ timeout: 15_000 }) - await tree.press('Escape') - } finally { - releaseCatalog() - await page.unroute(pattern) - } - }) - it('expands a persisted grandchild progressively without activating either level', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-tree')) - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() const catalogTree = page.getByRole('tree', { name: 'Subagent sessions' }) expect(await catalogTree.evaluate((element) => { const rect = element.getBoundingClientRect() const hit = document.elementFromPoint(rect.left + 8, rect.top + 8) return hit !== null && element.contains(hit) })).toBe(true) - expect(await page.getByRole('button', { + const oneShotDisclosure = page.getByRole('button', { name: `Expand ${ONE_SHOT_LABEL} descendants`, - }).count()).toBe(0) + }) + expect(await oneShotDisclosure.count()).toBe(0) const oneShotRow = page.getByRole('treeitem', { name: new RegExp(ONE_SHOT_LABEL) }) expect(await oneShotRow.locator('[data-state="done"]').count()).toBe(1) expect(await oneShotRow.getByText('~6mo 12d', { exact: true }).count()).toBe(1) @@ -402,12 +391,19 @@ describe('web e2e: persisted subagent conversation and human continuation', () = scaffold.workspaceCwd, ) await compareOrRefreshGolden(TREE_EXPECTED, snapshot, MODE) - await page.getByRole('tree', { name: 'Subagent sessions' }).press('Escape') + await page.getByRole('treeitem', { name: new RegExp(NESTED_LABEL) }).click() + await page.getByText(NESTED_PROMPT).waitFor() + const hierarchy = page.getByRole('navigation', { name: 'Session hierarchy' }) + await hierarchy.getByRole('button', { name: `Switch subagent: ${LABEL}`, exact: true }).waitFor() + expect(scaffold.ctx.agents.get(childId)).toBeUndefined() + expect(scaffold.ctx.agents.get(grandchildId)).toBeUndefined() + await hierarchy.getByRole('button').first().click() + await page.getByRole('button', { name: '2 subagents', exact: true }).waitFor() }) it('opens child history in the right Sidebar and releases it when closed', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-sidebar-chat')) - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() await page.getByRole('button', { name: `Open ${LABEL} in sidebar` }).click() const sidebarChat = page.locator('[data-sidebar-chat]') await sidebarChat.getByText(/^Explain event sourcing in one sentence\.Your parent agent id is /).waitFor({ timeout: 15_000 }) @@ -419,7 +415,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await page.locator('[data-sidebar-right-panel] [data-dockkit-tab-close]').click() await sidebarChat.waitFor({ state: 'detached' }) - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() await page.getByRole('button', { name: `Open ${ONE_SHOT_LABEL} in sidebar` }).click() await page.locator('[data-sidebar-chat]').getByText( 'One-shot tasks do not accept follow-ups; review the full execution record here.', @@ -430,7 +426,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () = it('opens the completed child from persistence without activating it', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-open')) - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click() await expect.poll( () => page.getByText(/^Explain event sourcing in one sentence\.Your parent agent id is /).count(), @@ -449,9 +445,9 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await compareOrRefreshGolden(SIDEBAR_EXPECTED, sidebar, MODE) }) - it('keeps a restored child neutral until its parent availability arrives', async () => { + it('waits for the initial catalog before restoring a saved child', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-restore')) - const pattern = '**/api/subagents/list' + const pattern = '**/api/session/list' let requested = false let releaseCatalog = (): void => {} const catalogHeld = new Promise((resolve) => { releaseCatalog = resolve }) @@ -468,16 +464,17 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) await expect.poll(() => requested, { timeout: 15_000 }).toBe(true) expect(await page.getByText('This subagent is read-only for now', { exact: true }).count()).toBe(0) - expect(await page.locator('[data-composer-seat]').evaluate(element => - getComputedStyle(element).visibility)).toBe('hidden') + expect(await page.getByRole('navigation', { name: 'Session hierarchy' }).count()).toBe(0) + expect(await page.getByText(/^Explain event sourcing in one sentence\.Your parent agent id is /).count()).toBe(0) releaseCatalog() + await page.getByRole('button', { name: `Switch subagent: ${LABEL}` }).waitFor({ timeout: 15_000 }) const input = page.getByRole('textbox', { name: 'Message or run a task, / commands, @ files or sessions' }) await input.waitFor({ timeout: 15_000 }) await expect.poll(() => input.isEnabled(), { timeout: 15_000 }).toBe(true) acknowledgeReloadConnectionLoss(tripwire, warningStart) } finally { releaseCatalog() - await page.unroute(pattern) + await page.unrouteAll({ behavior: 'wait' }) } }) @@ -529,6 +526,10 @@ describe('web e2e: persisted subagent conversation and human continuation', () = const tree = page.getByRole('tree', { name: 'Subagent sessions' }) const nestedRow = tree.locator('[role="treeitem"]').filter({ hasText: NESTED_LABEL }) await nestedRow.waitFor({ timeout: 15_000 }) + const nestedDisclosure = page.getByRole('button', { + name: `Expand ${NESTED_LABEL} descendants`, + }) + expect(await nestedDisclosure.count()).toBe(0) const clickArea = nestedRow.locator(':scope > div') expect(await clickArea.count()).toBe(1) const [treeBox, clickAreaBox] = await Promise.all([ @@ -569,10 +570,9 @@ describe('web e2e: persisted subagent conversation and human continuation', () = it('opens a one-shot child as permanently read-only history', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-one-shot')) const parentSession = page.getByRole('tree', { name: 'Sessions' }) - .getByRole('treeitem') - .last() + .getByRole('treeitem', { name: /Ask a research subagent to/ }) await parentSession.click() - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() await page.getByRole('treeitem', { name: new RegExp(ONE_SHOT_LABEL) }).click() await page.getByText('One-shot tasks do not accept follow-ups; review the full execution record here.').waitFor() expect(scaffold.ctx.agents.get(oneShotId)).toBeUndefined() @@ -583,7 +583,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await page.getByRole('tree', { name: 'Sessions' }) .getByRole('treeitem', { name: /Ask a research subagent to/ }) .click() - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click() await page.getByRole('textbox', { name: 'Message or run a task, / commands, @ files or sessions' }).waitFor() const forkResponse = page.waitForResponse(response => @@ -612,7 +612,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () = onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-post-fork-followup')) const sessions = page.getByRole('tree', { name: 'Sessions' }) await sessions.getByRole('treeitem', { name: /Ask a research subagent to/ }).click() - await page.getByRole('button', { name: '3 subagents' }).hover() + await page.getByRole('button', { name: '2 subagents' }).hover() await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click() await page.locator('[data-composer-input][contenteditable="true"]').first().waitFor() expect(scaffold.ctx.agents.get(childId)).toBeUndefined() @@ -629,7 +629,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () = await expect.poll(() => scaffold.ctx.agents.get(forkId)).not.toBeUndefined() await sessions.getByRole('treeitem', { name: /Ask a research subagent to/ }).click() - await page.getByRole('button', { name: '3 subagents' }).press('ArrowDown') + await page.getByRole('button', { name: '2 subagents' }).press('ArrowDown') await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click() const input = page.locator('[data-composer-input][contenteditable="true"]').first() await input.waitFor() diff --git a/apps/web/tests/subagent-interrupt-ui.e2e.ts b/apps/web/tests/subagent-interrupt-ui.e2e.ts index 11d96c63fd..7e71c1f8bb 100644 --- a/apps/web/tests/subagent-interrupt-ui.e2e.ts +++ b/apps/web/tests/subagent-interrupt-ui.e2e.ts @@ -185,20 +185,25 @@ describe.skipIf(MODE === 'record')('web e2e: composer interrupt for a running co it('interrupts the live child through the parent-offline composer', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-interrupt-offline')) - // Simulate a parent that went offline: the catalog delivers - // parentAvailable: false while the child Activation stays live (the - // interrupt RPC itself needs no live parent — covered host-side by - // subagent-interrupt.e2e.ts). - const pattern = '**/api/subagents/list' + // The parent is unavailable in the Session list while the child stays live. + const pattern = '**/api/session/list' await page.route(pattern, async (route) => { const response = await route.fetch() const body = await response.json() as { - result: { ok: true; value: { parentAvailable: boolean } } | { ok: false } + result: { ok: true; value: { items: { sessionId: SessionId; agentAvailable: boolean }[] } } | { ok: false } + } + if (body.result.ok) { + const summary = body.result.value.items.find(session => session.sessionId === parent.id) + if (summary === undefined) throw new Error('parent missing from Session list') + summary.agentAvailable = false } - if (body.result.ok) body.result.value.parentAvailable = false await route.fulfill({ response, json: body }) }) try { + const warningStart = tripwire.warnings.length + await page.reload({ waitUntil: 'load' }) + await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) + acknowledgeReloadConnectionLoss(tripwire, warningStart) await page.getByRole('button', { name: /1 subagent/ }).click() await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click() const input = page.getByRole('textbox', { @@ -264,7 +269,11 @@ describe.skipIf(MODE === 'record')('web e2e: composer interrupt for a running co it('interrupts through subagents/interruptByParent, parks the follow-up, and resumes it FIFO', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-interrupt-flow')) - // Reselect the child with the truthful catalog: parent available again. + // A new connection reloads the truthful parent-availability hint. + const warningStart = tripwire.warnings.length + await page.reload({ waitUntil: 'load' }) + await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) + acknowledgeReloadConnectionLoss(tripwire, warningStart) await page.getByRole('navigation', { name: 'Session hierarchy' }) .getByRole('button').first().click() await page.getByRole('button', { name: /1 subagent/ }).click() diff --git a/apps/web/tests/web-search-round.e2e.ts b/apps/web/tests/web-search-round.e2e.ts index 4128d0d46e..506c8abe34 100644 --- a/apps/web/tests/web-search-round.e2e.ts +++ b/apps/web/tests/web-search-round.e2e.ts @@ -239,9 +239,9 @@ describe('web e2e: shipped default web search', () => { event.type === 'tool/result' && event.data.message.source.callId === searchCall.data.callId, ) if (searchResult === undefined) throw new Error('web_search produced no durable result') - const content = searchResult.data.message.content[0] - expect(content.isError).toBe(false) - const rendered = content.content.filter(block => block.type === 'text').map(block => block.text).join('') + const message = searchResult.data.message + expect(message.isError).toBe(false) + const rendered = message.content.filter(block => block.type === 'text').map(block => block.text).join('') // The tool interleaves sources from both seam results before applying the // combined cap, so each query remains represented in model-visible output. for (const source of KEPT_SOURCES) { diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 56fe6bf139..4508e03def 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -94,6 +94,7 @@ "tests/file-upload-round.e2e.ts", "tests/message-actions.e2e.ts", "tests/open-in-app-ssh.e2e.ts", + "tests/fork-mid-turn.e2e.ts", "tests/message-feedback.e2e.ts", "tests/markdown-images.e2e.ts", "tests/markdown-file-links.e2e.ts", diff --git a/benchmarks/agent-continuation/child-catalog.worker.ts b/benchmarks/agent-continuation/child-catalog.worker.ts index e12cb97d2f..831a15c1b8 100644 --- a/benchmarks/agent-continuation/child-catalog.worker.ts +++ b/benchmarks/agent-continuation/child-catalog.worker.ts @@ -1,4 +1,4 @@ -/** Cold catalog observations of persisted fork children with tool-heavy inherited histories. */ +/** Cold parent-catalog observations beside fork children with tool-heavy inherited histories. */ import { performance } from 'node:perf_hooks' import { Context } from '@deepseek-ai/cordis' @@ -11,7 +11,7 @@ import SubagentRuntime, { SUBAGENT_DESCRIPTOR_VERSION } from '@deepseek-ai/dsh-s import { assertBuiltBenchmarkRuntime } from '../support/built-worker.ts' import { PARENT_ID, syntheticHistory, TIME_ZERO, WORKLOAD } from './workload.ts' -/** Two complete catalog reads in one fresh Host, with every child observation released. */ +/** Two complete catalog reads in one fresh Host, with each parent observation released. */ export interface CatalogReport { readonly totalMs: number readonly firstMs: number @@ -33,8 +33,14 @@ class CatalogQuery extends SessionQueryEngine { async function seed(ctx: Context): Promise { const inherited = syntheticHistory(WORKLOAD.childHistoryTurns) + const catalog: SessionEvent[] = [] for (let child = 0; child < WORKLOAD.children; child++) { const id = SessionId('bench-child-' + String(child)) + catalog.push({ + type: 'subagent/catalog', seq: SessionSeq(child), time: TIME_ZERO + child, + data: { version: 0, childId: id, childCreatedAt: TIME_ZERO + child, + mode: 'continuable', label: 'Synthetic child ' + String(child) }, + }) const events: SessionEvent[] = [ ...inherited, { type: 'session/end-seed', seq: SessionSeq(inherited.length), time: TIME_ZERO + inherited.length, data: { inherited: true } }, @@ -51,6 +57,14 @@ async function seed(ctx: Context): Promise { await handle.flush() } finally { await handle.close() } } + const parent = await ctx.sessionPersistence.create({ + version: SESSION_FORMAT_VERSION, id: PARENT_ID, createdAt: TIME_ZERO, cwd: '/bench', + isSeeded: false, + }) + try { + await parent.append(catalog) + await parent.flush() + } finally { await parent.close() } } async function run(root: string, mode: string): Promise { @@ -65,15 +79,15 @@ async function run(root: string, mode: string): Promise ctx.subagents.listChildren(PARENT_ID) const cpuStart = process.cpuUsage() const start = performance.now() - const first = await ctx.subagents.listChildren(PARENT_ID) + const first = await readCatalog() const firstDone = performance.now() - const repeated = await ctx.subagents.listChildren(PARENT_ID) + const repeated = await readCatalog() const end = performance.now() const cpu = process.cpuUsage(cpuStart) - if (first.length !== WORKLOAD.children || repeated.length !== WORKLOAD.children - || [...first, ...repeated].some(row => row.kind !== 'child')) { + if (first.length !== WORKLOAD.children || repeated.length !== WORKLOAD.children) { throw new Error('child-catalog benchmark did not reach the complete healthy catalog') } return { diff --git a/benchmarks/agent-continuation/profile-continuation.worker.ts b/benchmarks/agent-continuation/profile-continuation.worker.ts index 531fc2f50d..f744add964 100644 --- a/benchmarks/agent-continuation/profile-continuation.worker.ts +++ b/benchmarks/agent-continuation/profile-continuation.worker.ts @@ -62,8 +62,8 @@ async function run(root: string): Promise { requests += result.events.filter(event => event.type === 'assistant/message').length for (const event of result.events) { if (event.type !== 'tool/result') continue - const result = event.data.message.content[0] - if (result.isError || !result.content.some(block => block.type === 'text' && block.text.includes('export const synthetic = 42;'))) { + const message = event.data.message + if (message.isError || !message.content.some(block => block.type === 'text' && block.text.includes('export const synthetic = 42;'))) { throw new Error('profile benchmark did not read the synthetic file') } toolCalls++ diff --git a/benchmarks/agent-continuation/synthetic-history.bench.ts b/benchmarks/agent-continuation/synthetic-history.bench.ts index 6329db885c..d36dfc4c13 100644 --- a/benchmarks/agent-continuation/synthetic-history.bench.ts +++ b/benchmarks/agent-continuation/synthetic-history.bench.ts @@ -23,7 +23,7 @@ for (const [name, generate] of [ session.append('turn/start', { turn }) session.append('step/start', { turn, step: 1 }) const replacement = session.append('system/message', { - turn, step: 1, message: createSystemMessage('Next synthetic prompt', '@deepseek-ai/dsh-system-prompt'), + turn, step: 1, message: createSystemMessage('Next synthetic prompt'), }, { surfaceOp: { op: 'replace', startSeq: head, endSeq: head }, sourceEventSeqs: [head] }) const restored = Session.create(SessionId(header.id), parseSessionLog([ JSON.stringify(header), ...session.snapshotEvents().map(event => JSON.stringify(event)), diff --git a/benchmarks/agent-continuation/workload.ts b/benchmarks/agent-continuation/workload.ts index 20eae5d5ca..0cd4c5435b 100644 --- a/benchmarks/agent-continuation/workload.ts +++ b/benchmarks/agent-continuation/workload.ts @@ -69,7 +69,7 @@ export function syntheticHistory(turns: number): SessionEvent[] { session.append('turn/start', { turn }) session.append('step/start', { turn, step: 1 }) if (turn === 1) session.append('system/message', { - turn, step: 1, message: { id: MessageId('system-head'), role: 'system', content: [], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' } }, + turn, step: 1, message: { id: MessageId('system-head'), role: 'system', content: [], source: { kind: 'system-prompt' } }, }, { surfaceOp: 'append' }) session.append('user/message', { id: MessageId('prompt-' + String(turn)), role: 'user', @@ -91,8 +91,9 @@ export function syntheticHistory(turns: number): SessionEvent[] { session.append('tool/result', { turn, step, message: { - id: MessageId('result-' + block.id), role: 'user', source: { kind: 'tool', callId: block.id }, - content: [{ type: 'tool-result', toolCallId: block.id, content: [{ type: 'text', text: resultText(turn) }], isError: false }], + id: MessageId('result-' + block.id), role: 'tool', toolCallId: block.id, isError: false, + source: { kind: 'tool', callId: block.id }, + content: [{ type: 'text', text: resultText(turn) }], }, }, { surfaceOp: 'append', sourceEventSeqs: [call.seq] }) } diff --git a/benchmarks/long-session-browser/synthetic-history.ts b/benchmarks/long-session-browser/synthetic-history.ts index 32885489cb..cc2ecec551 100644 --- a/benchmarks/long-session-browser/synthetic-history.ts +++ b/benchmarks/long-session-browser/synthetic-history.ts @@ -28,7 +28,7 @@ export function syntheticHistory(): string { session.append('turn/start', { turn }) session.append('step/start', { turn, step: 1 }) if (turn === 1) session.append('system/message', { - turn, step: 1, message: createSystemMessage('', '@deepseek-ai/dsh-system-prompt'), + turn, step: 1, message: createSystemMessage(''), }, { surfaceOp: 'append' }) const user = session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'Review synthetic change ' + String(turn) + ': 检查增量渲染。 '.repeat(30) }], diff --git a/docs/config-catalog.i18n.yaml b/docs/config-catalog.i18n.yaml index 7733f352e1..782c44337b 100644 --- a/docs/config-catalog.i18n.yaml +++ b/docs/config-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/config-catalog.md -config-catalog.md: d802c5f084072dbe4f6654aecaf0640be96fb4bf -config-catalog.zh.md: b7c3b4be06b9ddf3fcd4117483fb0b1472493441 +config-catalog.md: 239da8f903a0031340deff551293ab96dd4333f0 +config-catalog.zh.md: e6279390fac6a81146e2ecebda56c7395415df30 diff --git a/docs/config-catalog.md b/docs/config-catalog.md index d802c5f084..239da8f903 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -111,7 +111,7 @@ export interface Config { Depends on: [`AgentOptions`](subsystems/core.md) · [`SessionId`](subsystems/core.md) -Source: [`packages/core/agent-loop/src/index.ts:318`](../packages/core/agent-loop/src/index.ts) +Source: [`packages/core/agent-loop/src/index.ts:319`](../packages/core/agent-loop/src/index.ts) @@ -213,7 +213,7 @@ export interface Config { } ``` -Source: [`packages/api/session-controller/src/index.ts:73`](../packages/api/session-controller/src/index.ts) +Source: [`packages/api/session-controller/src/index.ts:77`](../packages/api/session-controller/src/index.ts) @@ -549,7 +549,7 @@ export interface Config { } ``` -Source: [`packages/extensions/cordis-host-runner/src/index.ts:88`](../packages/extensions/cordis-host-runner/src/index.ts) +Source: [`packages/extensions/cordis-host-runner/src/index.ts:94`](../packages/extensions/cordis-host-runner/src/index.ts) @@ -996,7 +996,7 @@ export interface Config { } ``` -Source: [`packages/hooks/hooks-claude-code/src/index.ts:44`](../packages/hooks/hooks-claude-code/src/index.ts) +Source: [`packages/hooks/hooks-claude-code/src/index.ts:51`](../packages/hooks/hooks-claude-code/src/index.ts) @@ -1023,7 +1023,7 @@ export interface Config { } ``` -Source: [`packages/hooks/hooks-codex/src/index.ts:43`](../packages/hooks/hooks-codex/src/index.ts) +Source: [`packages/hooks/hooks-codex/src/index.ts:50`](../packages/hooks/hooks-codex/src/index.ts) @@ -1591,7 +1591,7 @@ export interface ReplayModelConfig { Depends on: [`ModelModality`](../packages/llm/llm/src/index.ts) · [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts) · [`SystemPromptUpdate`](../packages/llm/llm/src/index.ts) -Source: [`packages/test-support/llm-replay/src/index.ts:1122`](../packages/test-support/llm-replay/src/index.ts) +Source: [`packages/test-support/llm-replay/src/index.ts:1123`](../packages/test-support/llm-replay/src/index.ts) @@ -1874,7 +1874,7 @@ export interface PlanModeConfig { } ``` -Source: [`packages/plan/plan-mode/src/index.ts:64`](../packages/plan/plan-mode/src/index.ts) +Source: [`packages/plan/plan-mode/src/index.ts:70`](../packages/plan/plan-mode/src/index.ts) @@ -2045,7 +2045,7 @@ export interface Config { } ``` -Source: [`packages/guard/repeat-tool-reminder/src/index.ts:28`](../packages/guard/repeat-tool-reminder/src/index.ts) +Source: [`packages/guard/repeat-tool-reminder/src/index.ts:35`](../packages/guard/repeat-tool-reminder/src/index.ts) @@ -2206,7 +2206,7 @@ export interface Config { export type JsonlCompression = 'zstd' | 'none' ``` -Source: [`packages/session/session-persistence-jsonl/src/index.ts:88`](../packages/session/session-persistence-jsonl/src/index.ts) +Source: [`packages/session/session-persistence-jsonl/src/index.ts:90`](../packages/session/session-persistence-jsonl/src/index.ts) @@ -2680,7 +2680,7 @@ export interface Config { } ``` -Source: [`packages/subagent/subagent/src/index.ts:190`](../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:191`](../packages/subagent/subagent/src/index.ts) @@ -2989,7 +2989,7 @@ export interface Config { } ``` -Source: [`packages/context/time-context/src/index.ts:49`](../packages/context/time-context/src/index.ts) +Source: [`packages/context/time-context/src/index.ts:56`](../packages/context/time-context/src/index.ts) @@ -3005,7 +3005,7 @@ export interface Config { } ``` -Source: [`packages/context/tmux-context/src/index.ts:36`](../packages/context/tmux-context/src/index.ts) +Source: [`packages/context/tmux-context/src/index.ts:47`](../packages/context/tmux-context/src/index.ts) @@ -3129,7 +3129,7 @@ export interface Config { } ``` -Source: [`packages/goal/tool-goal/src/index.ts:25`](../packages/goal/tool-goal/src/index.ts) +Source: [`packages/goal/tool-goal/src/index.ts:32`](../packages/goal/tool-goal/src/index.ts) @@ -3163,7 +3163,7 @@ export interface Config { export type CompletionDelivery = 'quiet' | 'wakeup' ``` -Source: [`packages/jobs/tool-jobs/src/index.ts:31`](../packages/jobs/tool-jobs/src/index.ts) +Source: [`packages/jobs/tool-jobs/src/index.ts:37`](../packages/jobs/tool-jobs/src/index.ts) @@ -3504,7 +3504,7 @@ export interface Config { export type ToolPresentationMode = 'native' | 'ptc' | 'both' ``` -Source: [`packages/core/tools/src/index.ts:656`](../packages/core/tools/src/index.ts) +Source: [`packages/core/tools/src/index.ts:663`](../packages/core/tools/src/index.ts) @@ -3551,7 +3551,7 @@ export interface Config { export type ApprovalPolicy = 'ask' | 'never' ``` -Source: [`packages/interaction/user-approval/src/index.ts:128`](../packages/interaction/user-approval/src/index.ts) +Source: [`packages/interaction/user-approval/src/index.ts:135`](../packages/interaction/user-approval/src/index.ts) @@ -3936,6 +3936,7 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them. - `@deepseek-ai/dsh-session-format-v0-to-v1` ([`packages/session/session-format-v0-to-v1/src/index.ts`](../packages/session/session-format-v0-to-v1/src/index.ts)) - `@deepseek-ai/dsh-session-format-v1-to-v2` ([`packages/session/session-format-v1-to-v2/src/index.ts`](../packages/session/session-format-v1-to-v2/src/index.ts)) - `@deepseek-ai/dsh-session-format-v2-to-v3` ([`packages/session/session-format-v2-to-v3/src/index.ts`](../packages/session/session-format-v2-to-v3/src/index.ts)) +- `@deepseek-ai/dsh-session-format-v3-to-v4` ([`packages/session/session-format-v3-to-v4/src/index.ts`](../packages/session/session-format-v3-to-v4/src/index.ts)) - `@deepseek-ai/dsh-session-snapshot` ([`packages/test-support/session-snapshot/src/index.ts`](../packages/test-support/session-snapshot/src/index.ts)) - `@deepseek-ai/dsh-session-telemetry` ([`packages/session/session-telemetry/src/index.ts`](../packages/session/session-telemetry/src/index.ts)) - `@deepseek-ai/dsh-session-title-llm` ([`packages/session/session-title-llm/src/index.ts`](../packages/session/session-title-llm/src/index.ts)) diff --git a/docs/config-catalog.zh.md b/docs/config-catalog.zh.md index b7c3b4be06..e6279390fa 100644 --- a/docs/config-catalog.zh.md +++ b/docs/config-catalog.zh.md @@ -113,7 +113,7 @@ export interface Config { Depends on: [`AgentOptions`](subsystems/core.zh.md) · [`SessionId`](subsystems/core.zh.md) -来源:[`packages/core/agent-loop/src/index.ts:318`](../packages/core/agent-loop/src/index.ts) +来源:[`packages/core/agent-loop/src/index.ts:319`](../packages/core/agent-loop/src/index.ts) @@ -215,7 +215,7 @@ export interface Config { } ``` -来源:[`packages/api/session-controller/src/index.ts:73`](../packages/api/session-controller/src/index.ts) +来源:[`packages/api/session-controller/src/index.ts:77`](../packages/api/session-controller/src/index.ts) @@ -551,7 +551,7 @@ export interface Config { } ``` -来源:[`packages/extensions/cordis-host-runner/src/index.ts:88`](../packages/extensions/cordis-host-runner/src/index.ts) +来源:[`packages/extensions/cordis-host-runner/src/index.ts:94`](../packages/extensions/cordis-host-runner/src/index.ts) @@ -998,7 +998,7 @@ export interface Config { } ``` -来源:[`packages/hooks/hooks-claude-code/src/index.ts:44`](../packages/hooks/hooks-claude-code/src/index.ts) +来源:[`packages/hooks/hooks-claude-code/src/index.ts:51`](../packages/hooks/hooks-claude-code/src/index.ts) @@ -1025,7 +1025,7 @@ export interface Config { } ``` -来源:[`packages/hooks/hooks-codex/src/index.ts:43`](../packages/hooks/hooks-codex/src/index.ts) +来源:[`packages/hooks/hooks-codex/src/index.ts:50`](../packages/hooks/hooks-codex/src/index.ts) @@ -1593,7 +1593,7 @@ export interface ReplayModelConfig { Depends on: [`ModelModality`](../packages/llm/llm/src/index.ts) · [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts) · [`SystemPromptUpdate`](../packages/llm/llm/src/index.ts) -来源:[`packages/test-support/llm-replay/src/index.ts:1122`](../packages/test-support/llm-replay/src/index.ts) +来源:[`packages/test-support/llm-replay/src/index.ts:1123`](../packages/test-support/llm-replay/src/index.ts) @@ -1876,7 +1876,7 @@ export interface PlanModeConfig { } ``` -来源:[`packages/plan/plan-mode/src/index.ts:64`](../packages/plan/plan-mode/src/index.ts) +来源:[`packages/plan/plan-mode/src/index.ts:70`](../packages/plan/plan-mode/src/index.ts) @@ -2047,7 +2047,7 @@ export interface Config { } ``` -来源:[`packages/guard/repeat-tool-reminder/src/index.ts:28`](../packages/guard/repeat-tool-reminder/src/index.ts) +来源:[`packages/guard/repeat-tool-reminder/src/index.ts:35`](../packages/guard/repeat-tool-reminder/src/index.ts) @@ -2208,7 +2208,7 @@ export interface Config { export type JsonlCompression = 'zstd' | 'none' ``` -来源:[`packages/session/session-persistence-jsonl/src/index.ts:88`](../packages/session/session-persistence-jsonl/src/index.ts) +来源:[`packages/session/session-persistence-jsonl/src/index.ts:90`](../packages/session/session-persistence-jsonl/src/index.ts) @@ -2682,7 +2682,7 @@ export interface Config { } ``` -来源: [`packages/subagent/subagent/src/index.ts:190`](../packages/subagent/subagent/src/index.ts) +来源: [`packages/subagent/subagent/src/index.ts:191`](../packages/subagent/subagent/src/index.ts) @@ -2991,7 +2991,7 @@ export interface Config { } ``` -来源:[`packages/context/time-context/src/index.ts:49`](../packages/context/time-context/src/index.ts) +来源:[`packages/context/time-context/src/index.ts:56`](../packages/context/time-context/src/index.ts) @@ -3007,7 +3007,7 @@ export interface Config { } ``` -来源:[`packages/context/tmux-context/src/index.ts:36`](../packages/context/tmux-context/src/index.ts) +来源:[`packages/context/tmux-context/src/index.ts:47`](../packages/context/tmux-context/src/index.ts) @@ -3131,7 +3131,7 @@ export interface Config { } ``` -来源:[`packages/goal/tool-goal/src/index.ts:25`](../packages/goal/tool-goal/src/index.ts) +来源:[`packages/goal/tool-goal/src/index.ts:32`](../packages/goal/tool-goal/src/index.ts) @@ -3165,7 +3165,7 @@ export interface Config { export type CompletionDelivery = 'quiet' | 'wakeup' ``` -来源:[`packages/jobs/tool-jobs/src/index.ts:31`](../packages/jobs/tool-jobs/src/index.ts) +来源:[`packages/jobs/tool-jobs/src/index.ts:37`](../packages/jobs/tool-jobs/src/index.ts) @@ -3506,7 +3506,7 @@ export interface Config { export type ToolPresentationMode = 'native' | 'ptc' | 'both' ``` -来源:[`packages/core/tools/src/index.ts:656`](../packages/core/tools/src/index.ts) +来源:[`packages/core/tools/src/index.ts:663`](../packages/core/tools/src/index.ts) @@ -3553,7 +3553,7 @@ export interface Config { export type ApprovalPolicy = 'ask' | 'never' ``` -来源:[`packages/interaction/user-approval/src/index.ts:128`](../packages/interaction/user-approval/src/index.ts) +来源:[`packages/interaction/user-approval/src/index.ts:135`](../packages/interaction/user-approval/src/index.ts) @@ -3937,6 +3937,7 @@ export interface Config { - `@deepseek-ai/dsh-session-format-v0-to-v1`([`packages/session/session-format-v0-to-v1/src/index.ts`](../packages/session/session-format-v0-to-v1/src/index.ts)) - `@deepseek-ai/dsh-session-format-v1-to-v2`([`packages/session/session-format-v1-to-v2/src/index.ts`](../packages/session/session-format-v1-to-v2/src/index.ts)) - `@deepseek-ai/dsh-session-format-v2-to-v3`([`packages/session/session-format-v2-to-v3/src/index.ts`](../packages/session/session-format-v2-to-v3/src/index.ts)) +- `@deepseek-ai/dsh-session-format-v3-to-v4`([`packages/session/session-format-v3-to-v4/src/index.ts`](../packages/session/session-format-v3-to-v4/src/index.ts)) - `@deepseek-ai/dsh-session-snapshot`([`packages/test-support/session-snapshot/src/index.ts`](../packages/test-support/session-snapshot/src/index.ts)) - `@deepseek-ai/dsh-session-telemetry`([`packages/session/session-telemetry/src/index.ts`](../packages/session/session-telemetry/src/index.ts)) - `@deepseek-ai/dsh-session-title-llm`([`packages/session/session-title-llm/src/index.ts`](../packages/session/session-title-llm/src/index.ts)) diff --git a/docs/cookbook/adding-a-session-format-version.i18n.yaml b/docs/cookbook/adding-a-session-format-version.i18n.yaml index f66eda7447..fa995d7a2a 100644 --- a/docs/cookbook/adding-a-session-format-version.i18n.yaml +++ b/docs/cookbook/adding-a-session-format-version.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cookbook/adding-a-session-format-version.md -adding-a-session-format-version.md: 6ebc6bd2062acd88dab953bc227bc1046b13f083 -adding-a-session-format-version.zh.md: c66a045303f96c2ef237cf3b1c1dc598e9c8f5f6 +adding-a-session-format-version.md: 92efbefa943d6ea3c7d97ddeedb4a630e64edbf7 +adding-a-session-format-version.zh.md: 3cb1090b7ff259b7c7664261b3d7a2b3eaee6c13 diff --git a/docs/cookbook/adding-a-session-format-version.md b/docs/cookbook/adding-a-session-format-version.md index 6ebc6bd206..92efbefa94 100644 --- a/docs/cookbook/adding-a-session-format-version.md +++ b/docs/cookbook/adding-a-session-format-version.md @@ -14,18 +14,21 @@ Use this tutorial to introduce the next structural Session log version without r - [4. Update current-version consumers](#current-version-consumers) - [5. Create snapshot successors](#snapshot-successors) - [6. Validate the integrated result](#validate) +- [Developer V4 corpus trial](#v4-corpus-trial) - [Dev Note](#dev-note) ## 1. Choose the version and release base -Bump the format for a structural change to headers, event envelopes, core event semantics, or surface reconstruction. Ordinary event additions do not require a bump; follow the [versioning rule](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md). Distinguish the Session format integer from package release versions, SQLite schema versions, projection-unit versions, and protocol-wrapper versions. +Bump the format for a structural change to headers, event envelopes, core event semantics, or surface reconstruction. Backward-compatible changes can remain at the current version through new acknowledgements; follow the [versioning rule](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md) and [type-change rules](../persistence-changes/README.md#compatibility-rules). Distinguish the Session format integer from package release versions, SQLite schema versions, projection-unit versions, and protocol-wrapper versions. + +Let N be the accepted or published version in [version/status](../session-format-status.md) when planning the next breaking change. A breaking change after accepted V4 therefore needs V5 even before V4 publication is recorded; compatible additions do not require that step. Use a shared `release/*` integration base for N+1. The base change adds the writer, codec, catalog wiring, identity migration, and verification. Create each independent child branch from that base and target its PR at the release branch, not another independent child’s branch. Each child adds its structural transformation, validators, consumers, and tests to the same adjacent migration package. Do not allocate extra versions just to represent review order. Merge reviewed children into the release branch through PRs, then validate the combined result before release. Honor release-branch force-push and deletion protections; do not force-sync it. -Released codecs and migration semantics remain frozen. Do not amend a released edge to implement a new structural feature. Only the N→N+1 edge may incorporate coordinated changes before N+1 ships; after release, further structural changes need the next adjacent edge. +Released codecs and accepted target-format meanings remain stable. The N→N+1 converter may receive fixes or support additional historical cases after N+1 ships, without a version bump, if its output remains compatible with N+1. A converter fix affects subsequent conversions, not existing N+1 successors. Document changes to previously accepted mappings and how existing outputs remain supported. Changing the established target representation or interpretation incompatibly requires the next version. -Use disposable, isolated Harness homes for unreleased N+1 integration testing. An interim N+1 file already has the target writer version, so a later edit to N→N+1 will not migrate that file again. Re-run from unchanged historical input in a fresh test home; never repair this by rewriting a committed generation or reusing a real user's home. +Use disposable, isolated Harness homes while N+1 remains open for integration. An interim N+1 file already has the target writer version, so a later edit to N→N+1 will not migrate that file again. Re-run from unchanged historical input in a fresh test home; never repair this by rewriting a committed generation or reusing a real user's home. Before changing the writer, use the [archive command](../persistence-changes/historical-formats/README.md#maintenance) to preserve its complete persistence schema, then add the bilingual format reference under `docs/persistence-changes/historical-formats/vN.*`. Preserve all earlier records. The format coverage check requires every integer below the new writer to have its own document; the current generated catalog covers only the new writer. @@ -55,12 +58,20 @@ Treat the inherited cut as a logical event count, not a physical row count. Expo Define the new edge's event admission and transformation rules explicitly. The [V2-to-V3 source audit](../../packages/session/session-format-v2-to-v3/README.md#source-audit) and [alpha V0→V1 rule](../../.agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.md) own the policies of those released edges, not the new edge. Do not generalize either to every edge. A change to structure or event positions requires classifying source events, payload members, and references, and explicitly deciding whether opaque data can remain valid. [Equal-version retention](../../.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.md) alone does not prove a structural transformation safe. Validate target semantics and give each newly accepted case a rejecting counterexample; never widen older edges to hide an unsupported transformation. +Use native writer output as the conversion oracle: replay the same recorded LLM messages, tool outputs, and other inputs through the old and target writers. Compare migrated old output with raw target output before any format-normalizing helper; mask only documented volatile fields. For V4, ordinary tool results become flat tool-role messages with ordinary content blocks. A theoretically permitted old structure alone does not justify a new core content type. + +Alpha converters may explicitly refuse historical cases without an implemented, evidenced mapping, including otherwise valid logs. Keep the source unchanged and publish no partial successor. Prefer real corpora and reproducible writers when extending support; inspect user corpora read-only and create sanitized regression fixtures. + +Document only the identifier and field mappings needed by the target format in the edge README, with a reason for each. Do not add namespaces to direct source kinds or ordinary metadata solely because they are extensible. Preserve opaque nested data. Alpha converters may refuse unexpected source fields that would acquire new target meanings rather than invent an interpretation. + +Maintain the new edge's README as its single complete transformation and admission catalog, following the [V2-to-V3 specification](../../packages/session/session-format-v2-to-v3/README.md#v2-to-v3-specification). Enumerate every converted header, event, message slot, and payload field; exact rename or collision rules; preserved ids, coordinates, references, and inherited cuts; external prerequisites; refusal and opaque-data policies; and unsupported or deferred behavior. Separate historical source conversion from native target admission, and state which codec, restorer, installed validator, and recovery policy performs each check. Record any validation that is deliberately narrower than the declared schema. Update this catalog in the same change as its code; a generated schema inventory or PR description does not replace it. + Prove strict restoration through `sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' })`, feeding rows in order and calling `finish()`. This exercises physical decoding, the complete chain, and installed current Session validation. Production's recoverable/transformed policy is not a replacement for strict fixture and publication verification. Preserve documented historical validation exceptions rather than claiming stricter source validation than the edge actually performs. ## 4. Update current-version consumers -Trace each current-version consumer, including Session creation/restoration, JSONL filename selection and publication, the catalog's current encoder/restorer, projection-cache generation identity, replay and snapshot normalization, and TypeScript/Python SDK recordings. Use the writer constant where a value means current; keep literal historical versions in released codecs and historical fixtures. Update current documentation and generated references through their owners. +Trace each current-version consumer, including Session creation/restoration, JSONL filename selection and publication, the catalog's current encoder/restorer, projection-cache generation identity, replay and snapshot normalization, [physical fixture-layout validation](../../scripts/session-fixture-layout.ts), and TypeScript/Python SDK recordings. Use the writer constant where a value means current; keep literal historical versions in released codecs and historical fixtures. Update current documentation and generated references through their owners. Do not bump unrelated versions automatically. A request wrapper's `sessionFormatVersion` identifies its embedded Session generation; its outer schema version has its own meaning. Projection-unit state versions likewise do not replace the cache's Session-generation identity. @@ -69,7 +80,7 @@ Verify both read and write paths. Header-only listing must not read bodies or pu ## 5. Create snapshot successors -Read [snapshot ownership](../../snapshots/AGENTS.md) and the [snapshot library](../../packages/test-support/session-snapshot/README.md). Select the owning scenario, not an adapter that only references it. After implementing N+1, keep each historical file and generate its successor using the target version’s canonical parent and child filenames. Never rename a predecessor to the target filename or change only its header. +Read [snapshot ownership](../../snapshots/AGENTS.md) and the [snapshot library](../../packages/test-support/session-snapshot/README.md). The [corpus policy](../../scripts/session-snapshot-corpus-policy.ts) keeps its declared baseline as replay input so upgrades exercise the adjacent chain; a writer bump does not require refreshing that corpus. Select the owning scenario when a current-generation successor is needed, keep each historical file, and use the target version’s canonical parent and child filenames. Never rename a predecessor to the target filename or change only its header. For unchanged replay input, use keyless refresh on the owner, then replay without write-back. These SDK commands use `text-turn` and the checkout's writer version. Implement and wire N+1 before using them to generate that version, and select the actual affected owner for a feature: @@ -80,7 +91,7 @@ pnpm run test:snapshot snapshots/sdk/sdk.snapshot.ts -t text-turn Review the new generation, request sidecars, and protocol output together. Verify every predecessor remains byte-identical and that parent/child roles remain contiguous. Selection uses the numerically highest generation, so update shared references to the owner's selected parent. Do not use the packed-layout migrator as a version upgrader. If the model transcript must change, the scenario owner uses live recording under the [testing policy](../testing.md), with its required provider key. -Keep deliberate historical cases explicit through `snapshot.yml`'s `sessionFormat.version` and supported `coverage` names; record and refresh leave their Session fixtures untouched. Update the [corpus policy](../../scripts/session-snapshot-corpus-policy.ts) for the current generation while retaining focused direct-edge, multi-hop, packed-row, retry/failure, and shipped-profile coverage. Check the corpus and both SDK projections; do not mass-refresh unrelated scenarios merely to silence a validation failure. +Keep cases older than the retained baseline explicit through `snapshot.yml`'s `sessionFormat.version` and supported `coverage` names; record and refresh leave pinned Session fixtures untouched. Update the [corpus policy](../../scripts/session-snapshot-corpus-policy.ts) for the current generation while retaining focused direct-edge, multi-hop, packed-row, retry/failure, and shipped-profile coverage. Check the corpus and both SDK projections; do not mass-refresh unrelated scenarios merely to silence a validation failure. ## 6. Validate the integrated result @@ -105,6 +116,33 @@ pnpm run lint git diff --check ``` + +### Developer V4 corpus trial + +Use the one-time [migration script](../../scripts/migrate-sessions-to-v4.ts) from an installed contributor checkout whose writer is V4. Stop DSH processes using the target root before starting so writer locks and changing child logs do not prevent migration. Run from the repository root: + +```sh +pnpm run migrate:sessions-to-v4 +``` + +The default root is `~/.dsh/sessions`. Use `--sessions-dir /path/to/sessions-copy` for another corpus, or `--help` for usage. Each historical Session goes through the normal locked, validated publication path to create a V4 successor beside its unchanged source files. Existing V4 Sessions are opened read-only; rerunning does not reconvert them. The script makes no model requests and does not change conversion or refusal rules. + +The terminal reports each Session's selected file, version, progress, outcome, and elapsed time. Individual errors do not stop later Sessions. The final summary lists every failure and the full diagnostic log under the system temporary directory; any failure returns a nonzero exit status. Include that log and the printed checkout commit when reporting a migration problem. The report distinguishes Sessions converted during this run from those already at V4. + + +### Final V3 event vocabulary before V4 publication + +While the published format remains V3 and the integration writer is V4, master can still add valid V3 event types. After each master integration and before the first V4 publication, compare the migration-owned `RELEASED_V3_EVENT_TYPES` with the latest V3-writer commit used by that refresh. Capture its full immutable id while the locally verified `origin/master` still writes V3: + +```sh +V3_SOURCE_REF="$(git rev-parse --verify 'origin/master^{commit}')" +pnpm run verify-v3-event-vocabulary --source-ref "$V3_SOURCE_REF" +``` + +The verifier reads only that local commit and requires exact event-name equality. It rejects missing V3 names, extra copied names, and a source writer other than V3. In particular, V4-only `developer/message` must not enter the frozen V3 set. Review each difference against the V3 payload, required conversions, target admission, and consumers; adding the name alone does not establish a complete migration. Add the corresponding migration regression before accepting a new source event. + +This command does not fetch or establish remote freshness. The release operator must verify that the selected commit is the latest V3 writer included in the integration; an old remote-tracking ref or passing result for an older pin is insufficient. Record the checked id with release validation. If master already writes V4, reuse the recorded final V3 commit rather than resolving current master. After V4 ships, keep the V3 vocabulary tied to that historical source; later V4 event additions do not update it. Regular static CI has no dependency on a mutable master ref. + ## Dev Note diff --git a/docs/cookbook/adding-a-session-format-version.zh.md b/docs/cookbook/adding-a-session-format-version.zh.md index c66a045303..3cb1090b7f 100644 --- a/docs/cookbook/adding-a-session-format-version.zh.md +++ b/docs/cookbook/adding-a-session-format-version.zh.md @@ -14,18 +14,21 @@ - [4. 更新当前版本消费方](#current-version-consumers) - [5. 创建快照后继代际](#snapshot-successors) - [6. 验证集成结果](#validate) +- [开发者 V4 日志集试迁移](#v4-corpus-trial) - [开发备注](#dev-note) ## 1. 选择版本与发布基线 -当 header、事件信封、核心事件语义或表面重建发生结构性变更时,提升格式版本。普通事件新增不需要提升版本;遵循[版本规则](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md)。区分 Session 格式整数与包发布版本、SQLite schema 版本、投影单元版本及协议包装层版本。 +当 header、事件信封、核心事件语义或表面重建发生结构性变更时,提升格式版本。向后兼容的变更可以通过新的确认记录保留当前版本;遵循[版本规则](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md)与[类型变更规则](../persistence-changes/README.zh.md#compatibility-rules)。区分 Session 格式整数与包发布版本、SQLite schema 版本、投影单元版本及协议包装层版本。 + +规划下一次破坏性变更时,N 取[版本/状态](../session-format-status.zh.md)中的已接受或已发布版本。因此,即使尚未记录 V4 发布,已接受 V4 之后的破坏性变更也需要 V5;兼容新增不需要这一步。 为 N+1 使用共享的 `release/*` 集成基线。基线变更添加写入器、codec、catalog 接线、恒等迁移与验证。从该基线创建各个独立子分支,并将其 PR(Pull Request)的目标设为发布分支,而非另一个独立子分支。每个子分支在同一个相邻迁移包内添加自身的结构变换、校验器、消费方和测试。不要只为表示评审顺序而分配额外版本。通过 PR 将评审后的子分支合入发布分支,并在发布前验证组合结果。遵守发布分支的强制推送与删除保护;不要强制同步该分支。 -已发布 codec 和迁移语义保持冻结。不要通过修改已发布迁移边来实现新的结构性功能。只有 N→N+1 迁移边可在 N+1 发布前纳入协同变更;发布后,进一步的结构性变更需要下一条相邻迁移边。 +已发布 codec 和已接受的目标格式含义保持稳定。N+1 发布后,N→N+1 转换器仍可修复或增加历史场景支持;只要输出仍兼容 N+1,就不必提高版本。转换器修复只影响之后的转换,不会重新处理已有 N+1 后继文件。记录对原先已接纳映射的修改,以及已有输出如何继续得到支持。不兼容地改变既定目标表示或解释语义需要下一版本。 -未发布 N+1 的集成测试应使用可丢弃、相互隔离的 Harness home。中间版本产生的 N+1 文件已标为目标写入器版本,因此后续对 N→N+1 的修改不会再次迁移该文件。请在全新测试 home 中从未变更的历史输入重新运行;绝不通过改写已提交代际或复用真实用户 home 来修复这个问题。 +N+1 尚处于开放集成阶段时,应使用可丢弃、相互隔离的 Harness home。中间版本产生的 N+1 文件已标为目标写入器版本,因此后续对 N→N+1 的修改不会再次迁移该文件。请在全新测试 home 中从未变更的历史输入重新运行;绝不通过改写已提交代际或复用真实用户 home 来修复这个问题。 变更写入器之前,使用[归档命令](../persistence-changes/historical-formats/README.zh.md#maintenance)保留其完整持久化 schema,再在 `docs/persistence-changes/historical-formats/vN.*` 下添加双语格式参考。保留所有更早的记录。格式覆盖检查要求低于新写入器的每个整数版本都有独立文档;当前生成的目录只覆盖新写入器。 @@ -55,12 +58,20 @@ pnpm run gen-session-format-catalog 显式定义新迁移边的事件准入与变换规则。[V2 到 V3 源审计](../../packages/session/session-format-v2-to-v3/README.zh.md#source-audit)和 [Alpha V0→V1 规则](../../.agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.zh.md)分别负责对应已发布迁移边的策略,而非新迁移边的策略。不要将任一策略推广到所有迁移边。结构或事件位置变化时,必须分类源事件、载荷成员与引用,并显式判断不透明数据能否保持有效。[同版本保留](../../.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.zh.md)本身不能证明结构变换安全。校验目标语义,并为每个新增可接受案例提供一个被拒绝的反例;绝不放宽旧迁移边来掩盖不受支持的转换。 +以原生 writer 输出作为转换对照:用相同录制的 LLM 消息、工具输出和其他输入回放旧 writer 与目标 writer。任何格式归一化 helper 运行前,比较迁移后的旧输出与目标原始输出,只屏蔽已说明的易变字段。V4 的普通工具结果变为包含普通内容块的平铺 tool-role 消息。旧类型理论上允许某种结构,本身不足以支持新增核心内容类型。 + +Alpha 转换器可以明确拒绝尚无已实现、有证据映射的历史场景,包括原本有效的日志。源文件保持不变,且不发布部分 successor。扩展支持时优先使用真实语料和可复现 writer;只读检查用户语料,并创建脱敏回归 fixture。 + +在迁移边 README 中只记录目标格式所需的标识符与字段映射,并逐项说明原因。不要仅因可扩展就给直接 source kind 或普通 metadata 添加命名空间。保留不透明嵌套数据。Alpha 转换器可以拒绝在目标格式中会获得新语义的意外源字段,而不是为其虚构解释。 + +参照 [V2 到 V3 规范](../../packages/session/session-format-v2-to-v3/README.zh.md#v2-to-v3-specification),将新迁移边的 README 维护为唯一完整的转换与接纳目录。枚举每个被转换的 header、事件、消息槽和载荷字段,精确重命名或冲突规则,保留的 id、坐标、引用与继承截点,外部前置证据,拒绝与不透明数据策略,以及不支持或延后的行为。将历史源转换与原生目标接纳分开,说明每项检查由哪个 codec、restorer、已安装校验器和恢复策略执行。记录刻意窄于声明 schema 的校验范围。代码变更必须同时更新此目录;生成的 schema 库存或 PR 描述不能替代它。 + 通过 `sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' })` 验证严格恢复,按顺序传入各行并调用 `finish()`。这会执行物理解码、完整迁移链与已安装当前 Session 校验。生产环境的 recoverable/transformed 策略不能替代 fixture(测试前置数据)和发布验证所需的严格校验。保留已记录的历史校验例外,不要宣称源校验比迁移边实际执行的更严格。 ## 4. 更新当前版本消费方 -追踪每个当前版本消费方,包括 Session 创建与恢复、JSONL 文件名选择与发布、catalog 的当前编码器与恢复器、投影缓存的代际身份、回放与快照归一化,以及 TypeScript/Python SDK 录制。当值表示当前版本时使用写入器常量;在已发布 codec 和历史 fixture 中保留字面历史版本。通过各自所有者更新当前文档与生成参考。 +追踪每个当前版本消费方,包括 Session 创建与恢复、JSONL 文件名选择与发布、catalog 的当前编码器与恢复器、投影缓存的代际身份、回放与快照归一化、[物理 fixture 布局校验](../../scripts/session-fixture-layout.ts),以及 TypeScript/Python SDK 录制。当值表示当前版本时使用写入器常量;在已发布 codec 和历史 fixture 中保留字面历史版本。通过各自所有者更新当前文档与生成参考。 不要自动提升无关版本。请求包装层的 `sessionFormatVersion` 标识嵌入的 Session 代际;外层 schema 版本有自己的含义。投影单元状态版本同样不能替代缓存的 Session 代际身份。 @@ -69,7 +80,7 @@ pnpm run gen-session-format-catalog ## 5. 创建快照后继代际 -阅读[快照所有权](../../snapshots/AGENTS.md)和[快照库](../../packages/test-support/session-snapshot/README.zh.md)。选择拥有数据的场景,而非仅引用它的适配器。实现 N+1 后,保留每份历史文件,并按目标版本的规范父子文件名生成后继文件。绝不将前代重命名为目标文件名,或仅修改其 header。 +阅读[快照所有权](../../snapshots/AGENTS.md)和[快照库](../../packages/test-support/session-snapshot/README.zh.md)。[语料策略](../../scripts/session-snapshot-corpus-policy.ts)保留其声明的 baseline 作为回放输入,让升级实际经过相邻迁移链;提高 writer 版本不要求 refresh 该语料。需要当前代际后继时,选择拥有数据的场景,保留每份历史文件,并使用目标版本的规范父子文件名。绝不将前代重命名为目标文件名,或仅修改其 header。 如果回放输入不变,在所有者上执行无密钥 refresh,再执行不写回的 replay。以下 SDK 命令使用 `text-turn` 和工作区的写入器版本。先实现并接入 N+1,才能用它们生成该版本;功能变更应选择实际受影响的所有者: @@ -80,7 +91,7 @@ pnpm run test:snapshot snapshots/sdk/sdk.snapshot.ts -t text-turn 一起审查新代际、请求伴随文件与协议输出。验证每个前代的字节保持相同,且父子角色连续。选择规则采用数值最高的代际,因此应将共享引用更新为所有者选中的父代际。不要把 packed 布局迁移器当作版本升级器。如果模型 transcript(文本记录)必须变化,由场景所有者按照[测试策略](../testing.zh.md)使用所需提供方密钥进行实时录制。 -通过 `snapshot.yml` 的 `sessionFormat.version` 与受支持的 `coverage` 名称显式保留历史案例;record 和 refresh 不改动这些 Session fixture。更新[语料策略](../../scripts/session-snapshot-corpus-policy.ts)以采用当前代际,同时保留聚焦的直接迁移边、多跳、packed row、重试/失败及交付 profile 覆盖。检查语料和两个 SDK 投影;不要仅为消除校验失败而批量 refresh 无关场景。 +通过 `snapshot.yml` 的 `sessionFormat.version` 与受支持的 `coverage` 名称显式保留早于 baseline 的案例;record 和 refresh 不改动已 pin 的 Session fixture。更新[语料策略](../../scripts/session-snapshot-corpus-policy.ts)以采用当前代际,同时保留聚焦的直接迁移边、多跳、packed row、重试/失败及交付 profile 覆盖。检查语料和两个 SDK 投影;不要仅为消除校验失败而批量 refresh 无关场景。 ## 6. 验证集成结果 @@ -105,6 +116,33 @@ pnpm run lint git diff --check ``` + +### 开发者 V4 日志集试迁移 + +在已安装依赖、写入器为 V4 的贡献者工作区中使用这个一次性[迁移脚本](../../scripts/migrate-sessions-to-v4.ts)。开始前停止使用目标根目录的 DSH 进程,避免写入锁及变化中的子日志阻止迁移。在仓库根目录运行: + +```sh +pnpm run migrate:sessions-to-v4 +``` + +默认根目录是 `~/.dsh/sessions`。可用 `--sessions-dir /path/to/sessions-copy` 指定其他日志集,或用 `--help` 查看用法。每个历史 Session 都通过正常的加锁、校验和发布流程,在未修改的源文件旁创建 V4 后继。已有 V4 Session 仅以只读方式打开;重复运行不会重新转换它们。脚本不发起模型请求,也不改变转换或拒绝规则。 + +终端逐个报告 Session 选中的文件、版本、进度、结果和耗时。单个错误不会阻止后续 Session。最终摘要列出全部失败项及系统临时目录中的完整诊断日志;存在任何失败时返回非零退出状态。报告迁移问题时,请附上该日志及输出的工作区 commit。报告区分本次转换成功的 Session 和运行前已为 V4 的 Session。 + + +### 发布 V4 前确认最终 V3 事件词汇 + +当已发布格式仍为 V3、集成写入方为 V4 时,master 仍可能新增有效的 V3 事件类型。每次集成 master 后及首次发布 V4 前,都要把迁移所有的 `RELEASED_V3_EVENT_TYPES` 与该次刷新使用的最新 V3 写入方提交比较。在已于本地核验的 `origin/master` 仍写入 V3 时,记录其完整、不可变的提交 id: + +```sh +V3_SOURCE_REF="$(git rev-parse --verify 'origin/master^{commit}')" +pnpm run verify-v3-event-vocabulary --source-ref "$V3_SOURCE_REF" +``` + +校验器只读取该本地提交,并要求事件名完全一致。它拒绝遗漏的 V3 名称、额外复制的名称,以及不写入 V3 的源提交。尤其不能把 V4 专有的 `developer/message` 放入冻结的 V3 集合。逐项核对 V3 payload、必要转换、目标接纳及消费方;只添加名称不能证明迁移完整。接受新源事件前要补上相应迁移回归。 + +此命令不会 fetch,也不能证明远端新鲜度。发布操作者必须确认所选提交是此次集成包含的最新 V3 写入方;陈旧的远端跟踪 ref 或旧 pin 的通过结果均不足。把核验过的 id 记入发布验证。如果 master 已写入 V4,应复用已记录的最终 V3 提交,而不再解析当前 master。V4 发布后,V3 词汇仍绑定该历史源码;后续 V4 事件新增不更新它。常规静态 CI 不依赖可变的 master ref。 + ## 开发备注 diff --git a/docs/cookbook/reviewing-persistence-type-changes.i18n.yaml b/docs/cookbook/reviewing-persistence-type-changes.i18n.yaml index 67a9df2ffb..94277ee348 100644 --- a/docs/cookbook/reviewing-persistence-type-changes.i18n.yaml +++ b/docs/cookbook/reviewing-persistence-type-changes.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cookbook/reviewing-persistence-type-changes.md -reviewing-persistence-type-changes.md: 881bc689af656f0c4976e909a49848e38d53c453 -reviewing-persistence-type-changes.zh.md: f1961013886cfab1abdbd7e2cd7e09bcfce2101d +reviewing-persistence-type-changes.md: 7baa6e5d9ee2d5ba72f9a3cc7c962153424010bc +reviewing-persistence-type-changes.zh.md: fec7494121ae8e500500c7a987b8c5221ebe35f8 diff --git a/docs/cookbook/reviewing-persistence-type-changes.md b/docs/cookbook/reviewing-persistence-type-changes.md index 881bc689af..7baa6e5d9e 100644 --- a/docs/cookbook/reviewing-persistence-type-changes.md +++ b/docs/cookbook/reviewing-persistence-type-changes.md @@ -33,9 +33,19 @@ Use `--silent` when consuming JSON: pnpm otherwise appends lifecycle failure tex Read the reported root, path, change kind, and version requirement. A referenced type can affect several event digests; inspect every affected root. Until the history covers the new schemas, verification fails. A stale generated inventory also fails verification; the recording command refreshes it. If `changes` is empty after reordering fields or union alternatives, run `pnpm run gen-persistence-catalog` and repeat the check. An unchanged digest needs no new acknowledgement even when copied declarations or source locations produce a catalog diff. +To review a PR independently of its acknowledgement history, save the base and head inventories as local JSON files and run: + +```sh +pnpm --silent run persistence-review --before .artifacts/base.schema.json --after docs/persistence-schema.json +``` + +Record the commits supplying those files with the report. Add `--json` for structured output. This read-only comparison groups shared changes with their affected roots and uses actual literal `kind`/`form` values instead of union positions. Ambiguous alternatives remain separate additions and removals. Its compatibility section copies every root's authoritative classifier result; the structural explanation does not replace acknowledgement checks. Current catalog labels and declaration names are descriptive metadata; structural anchors and fingerprints identify types. + ## 1. Record the change +Check the [accepted baseline](../session-format-status.md#finalization-record) first. Preserve its locked records. Record backward-compatible evolution in a new same-version acknowledgement; implement a higher writer version before recording a breaking change. + Write a local JSON file containing `en` and `zh`, each with `summary`, `compatibility`, and `verification` strings. The following input describes an exercised required-to-optional hook audit field change. Replace the explanation and test evidence with facts about your change; the CLI does not establish these claims. Save the input as `.artifacts/persistence-change.prose.json`, creating the ignored directory if needed: @@ -87,7 +97,7 @@ If source changes after recording, review the compatibility explanation and refr pnpm --silent run persistence-changes --update 2026-09-11-poc-optional --prose .artifacts/persistence-change.prose.json --json ``` -The command refreshes the machine declaration, schemas, catalogs, and pairing. Without `--prose`, it preserves the existing explanation. Update refuses the initial baseline and records that another record depends on. The tree cannot identify which records were accepted in review: preserve accepted history and create a successor instead. +The command refreshes the machine declaration, schemas, catalogs, and pairing. Without `--prose`, it preserves the existing explanation. Update refuses the initial baseline, records that another record depends on, and finalized checkpoint records. Outside finalized checkpoints, the tree does not infer review acceptance: preserve accepted history and create a successor instead. When integration creates competing terminal records, update the unaccepted record against the remaining history, then reassess the resulting diff. An unrelated root's acknowledgement does not need refreshing. The [mechanism decision](../../.agents/notes/implemented/process/2026-09-11-persistence-type-history.md) explains why complete snapshots and per-root predecessors are retained. diff --git a/docs/cookbook/reviewing-persistence-type-changes.zh.md b/docs/cookbook/reviewing-persistence-type-changes.zh.md index f196101388..fec7494121 100644 --- a/docs/cookbook/reviewing-persistence-type-changes.zh.md +++ b/docs/cookbook/reviewing-persistence-type-changes.zh.md @@ -33,9 +33,19 @@ pnpm --silent run verify-persistence-changes --json 阅读报告中的根、路径、变更种类和版本要求。被引用类型可能影响多个事件摘要;检查每个受影响的根。在历史覆盖新 schema 之前,验证会失败。陈旧生成清单也会导致验证失败;记录命令会刷新它。若重排字段或联合类型分支后 `changes` 为空,运行 `pnpm run gen-persistence-catalog` 并重新检查。即使复制的声明或源码位置产生目录 diff,未变的摘要也无需新增确认记录。 +要独立于确认历史评审 PR,先将 base 和 head 的目录保存为本地 JSON 文件,再运行: + +```sh +pnpm --silent run persistence-review --before .artifacts/base.schema.json --after docs/persistence-schema.json +``` + +在报告旁记录这些文件对应的 commit。添加 `--json` 可获取结构化输出。此只读比较将共享变更与受影响的根类型归组,使用实际字面量 `kind`/`form` 值代替联合类型位置。无法唯一匹配的候选项保留为独立的新增与删除。兼容性部分复制每个根类型的权威分类结果;结构说明不替代确认检查。当前目录标签和声明名称是描述元数据;结构锚点和指纹标识类型。 + ## 1. 记录变更 +先检查[已接受基线](../session-format-status.zh.md#finalization-record),保留其锁定记录。向后兼容的演进使用新的同版本确认记录;记录破坏性变更之前,先实现更高的写入器版本。 + 编写包含 `en` 和 `zh` 的本地 JSON 文件,两者分别包含 `summary`、`compatibility` 和 `verification` 字符串。以下输入描述一个经过验证的钩子审计字段从必选改为可选的变更。用你所做变更的事实替换说明和测试证据;CLI(命令行界面)不会证明这些声明。 将输入保存为 `.artifacts/persistence-change.prose.json`,必要时创建该被忽略的目录: @@ -87,7 +97,7 @@ pnpm run doc-sync pnpm --silent run persistence-changes --update 2026-09-11-poc-optional --prose .artifacts/persistence-change.prose.json --json ``` -命令刷新机器声明、schema、目录和配对。没有 `--prose` 时,它保留已有说明。更新会拒绝初始基线和被其他记录依赖的记录。目录本身无法识别哪些记录已获审阅接受:保留已接受历史,并创建后继。 +命令刷新机器声明、schema、目录和配对。没有 `--prose` 时,它保留已有说明。更新会拒绝初始基线、其他记录所依赖的记录,以及已被定稿检查点锁定的记录。定稿检查点之外,目录不会推断审阅接受状态:保留已接受历史,并创建后继。 集成产生竞争末端记录时,根据剩余历史更新尚未接受的记录,再重新评估最终差异。无关根的确认无需刷新。[机制决策](../../.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md)解释为何保留完整快照和逐根前驱。 diff --git a/docs/event-producer-consumer.i18n.yaml b/docs/event-producer-consumer.i18n.yaml index da7ba5ac03..93b1ac5fdc 100644 --- a/docs/event-producer-consumer.i18n.yaml +++ b/docs/event-producer-consumer.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/event-producer-consumer.md -event-producer-consumer.md: 06e602c36b3686de4b9b62a241cce18fe2260811 -event-producer-consumer.zh.md: fad6bc32e4d242cddac40545c02098c5fd17130d +event-producer-consumer.md: 550af905e80b1165df5e9d287bbf054f2989e5f0 +event-producer-consumer.zh.md: 1688477fca26ccbc561ff48ba01bb33cd2e58b6f diff --git a/docs/event-producer-consumer.md b/docs/event-producer-consumer.md index 06e602c36b..550af905e8 100644 --- a/docs/event-producer-consumer.md +++ b/docs/event-producer-consumer.md @@ -7,10 +7,10 @@ This matrix shows which packages dispatch each harness-owned event and which pac | Event | Mode | Declared in | Dispatchers | Listeners | | --- | --- | --- | --- | --- | -| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:246`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - | +| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:247`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - | | `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:82`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `remotes` | | `agent/assistant-stream` | `emit` | [`packages/core/agent/src/runtime-types.ts:363`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`headless`](../packages/bundle/headless), `session-controller` | -| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:261`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `browser-use-runtime`, [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), [`schedule`](../packages/schedule/schedule), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | +| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:261`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `browser-use-runtime`, [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), [`schedule`](../packages/schedule/schedule), `session-controller`, `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:270`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:393`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`session-telemetry`](../packages/session/session-telemetry) | | `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:299`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs) | @@ -21,15 +21,15 @@ This matrix shows which packages dispatch each harness-owned event and which pac | `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:353`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm-retry`](../packages/llm/llm-retry) | | `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:280`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server`, `session-controller` | | `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:381`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:587`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:567`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:594`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:573`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:580`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:600`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:580`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:607`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:586`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:593`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | | `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:85`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes` | | `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | [`authorization`](../packages/credentials/authorization) | | `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:89`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `remotes` | -| `compaction/summary-error` | `waterfall` | [`packages/compaction/compaction/src/index.ts:99`](../packages/compaction/compaction/src/index.ts) | [`compaction-basic`](../packages/compaction/compaction-basic) (`waterfall`) | [`compaction-image-offload`](../packages/compaction/compaction-image-offload) | +| `compaction/summary-error` | `waterfall` | [`packages/compaction/compaction/src/index.ts:106`](../packages/compaction/compaction/src/index.ts) | [`compaction-basic`](../packages/compaction/compaction-basic) (`waterfall`) | [`compaction-image-offload`](../packages/compaction/compaction-image-offload) | | `connection/request` | `waterfall` | [`packages/client/connection/src/index.ts:62`](../packages/client/connection/src/index.ts) | `connection` (`waterfall`) | - | | `cordis/dynamic-package` | `emit` | [`packages/extensions/cordis-host-runner/src/types.ts:380`](../packages/extensions/cordis-host-runner/src/types.ts) | [`cordis-host-runner`](../packages/extensions/cordis-host-runner) (`emit`) | `remotes` | | `cordis/dynamic-retract` | `emit` | [`packages/extensions/cordis-host-runner/src/types.ts:386`](../packages/extensions/cordis-host-runner/src/types.ts) | [`cordis-host-runner`](../packages/extensions/cordis-host-runner) (`emit`) | `remotes` | @@ -49,31 +49,31 @@ This matrix shows which packages dispatch each harness-owned event and which pac | `hmr/change` | `emit` | [`packages/boot/hmr/src/index.ts:30`](../packages/boot/hmr/src/index.ts) | [`hmr`](../packages/boot/hmr) (`emit`) | - | | `hmr/reload` | `emit` | [`packages/boot/hmr/src/index.ts:35`](../packages/boot/hmr/src/index.ts) | [`hmr`](../packages/boot/hmr) (`emit`) | - | | `llm/adapters-updated` | `emit` | [`packages/llm/llm/src/types.ts:23`](../packages/llm/llm/src/types.ts) | [`llm`](../packages/llm/llm) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`llm`](../packages/llm/llm), `remotes` | -| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:72`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) | +| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:73`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) | | `permission-presets/catalog-changed` | `emit` | [`packages/interaction/permission-presets/src/types.ts:44`](../packages/interaction/permission-presets/src/types.ts) | [`permission-presets`](../packages/interaction/permission-presets) (`events.dispatch`) | `remotes` | | `plugin-manager/changed` | `emit` | [`packages/boot/plugin-manager/src/types.ts:223`](../packages/boot/plugin-manager/src/types.ts) | [`plugin-manager`](../packages/boot/plugin-manager) (`emit`) | `remotes` | | `plugin-manager/install-log` | `emit` | [`packages/boot/plugin-manager/src/types.ts:229`](../packages/boot/plugin-manager/src/types.ts) | [`plugin-manager`](../packages/boot/plugin-manager) (`emit`) | `remotes` | | `plugin-manager/install-state` | `emit` | [`packages/boot/plugin-manager/src/types.ts:236`](../packages/boot/plugin-manager/src/types.ts) | [`plugin-manager`](../packages/boot/plugin-manager) (`emit`) | `remotes` | | `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - | -| `session/created` | `emit` | [`packages/core/session/src/index.ts:50`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), `session-controller`, [`session-log-deepseek`](../packages/session/session-log-deepseek), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | -| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:60`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `file-upload`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `session/event` | `emit` | [`packages/core/session/src/index.ts:72`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:81`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-telemetry`](../packages/session/session-telemetry) | +| `session/created` | `emit` | [`packages/core/session/src/index.ts:53`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), `session-controller`, [`session-log-deepseek`](../packages/session/session-log-deepseek), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | +| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:63`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `file-upload`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`workspace-changes`](../packages/deliverables/workspace-changes) | +| `session/event` | `emit` | [`packages/core/session/src/index.ts:75`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-changes`](../packages/deliverables/workspace-changes) | +| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:84`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-telemetry`](../packages/session/session-telemetry) | | `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:105`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `remotes` | | `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:92`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) | | `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:296`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - | -| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:172`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), `server`, [`subagent`](../packages/subagent/subagent) | -| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:146`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:152`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:163`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`subagent`](../packages/subagent/subagent) | +| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:173`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), `server`, [`subagent`](../packages/subagent/subagent) | +| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:147`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:153`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:164`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`subagent`](../packages/subagent/subagent) | | `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-presets`](../packages/preset/agent-presets), `browser-use-runtime`, [`session-reference`](../packages/context/session-reference), [`system-prompt`](../packages/core/system-prompt) | | `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - | -| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:201`](../packages/core/tools/src/index.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) | -| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:157`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` | -| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:169`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) | -| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:146`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:183`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) | -| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:191`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), [`subagent-in-process-driver`](../packages/subagent/subagent-in-process-driver), [`tool-present`](../packages/deliverables/tool-present) | +| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:208`](../packages/core/tools/src/index.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) | +| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:164`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` | +| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:176`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) | +| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:153`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) | +| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:190`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) | +| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:198`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), [`subagent-in-process-driver`](../packages/subagent/subagent-in-process-driver), [`tool-present`](../packages/deliverables/tool-present) | | `user-questions/request` | `waterfall` | [`packages/interaction/user-questions/src/types.ts:88`](../packages/interaction/user-questions/src/types.ts) | [`user-questions`](../packages/interaction/user-questions) (`waterfall`) | `remotes` | | `webserver/index-inject` | `emit` | [`packages/host/webserver/src/index.ts:34`](../packages/host/webserver/src/index.ts) | `webserver` (`emit`) | `connection`, `inspector`, `modules`, `ui-sidebar-documentpreview` | | `workflow/agent-end` | `emit` | [`packages/workflow/workflow/src/index.ts:79`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) | diff --git a/docs/event-producer-consumer.zh.md b/docs/event-producer-consumer.zh.md index fad6bc32e4..1688477fca 100644 --- a/docs/event-producer-consumer.zh.md +++ b/docs/event-producer-consumer.zh.md @@ -9,10 +9,10 @@ | Event | Mode | Declared in | Dispatchers | Listeners | | --- | --- | --- | --- | --- | -| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:246`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - | +| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:247`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - | | `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:82`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `remotes` | | `agent/assistant-stream` | `emit` | [`packages/core/agent/src/runtime-types.ts:363`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`headless`](../packages/bundle/headless), `session-controller` | -| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:261`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `browser-use-runtime`, [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), [`schedule`](../packages/schedule/schedule), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | +| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:261`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `browser-use-runtime`, [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), [`schedule`](../packages/schedule/schedule), `session-controller`, `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:270`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:393`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`session-telemetry`](../packages/session/session-telemetry) | | `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:299`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs) | @@ -23,15 +23,15 @@ | `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:353`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm-retry`](../packages/llm/llm-retry) | | `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:280`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server`, `session-controller` | | `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:381`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:587`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:567`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:594`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:573`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | -| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:580`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:600`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:580`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:607`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:586`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | +| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:593`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` | | `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:85`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes` | | `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | [`authorization`](../packages/credentials/authorization) | | `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:89`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `remotes` | -| `compaction/summary-error` | `waterfall` | [`packages/compaction/compaction/src/index.ts:99`](../packages/compaction/compaction/src/index.ts) | [`compaction-basic`](../packages/compaction/compaction-basic) (`waterfall`) | [`compaction-image-offload`](../packages/compaction/compaction-image-offload) | +| `compaction/summary-error` | `waterfall` | [`packages/compaction/compaction/src/index.ts:106`](../packages/compaction/compaction/src/index.ts) | [`compaction-basic`](../packages/compaction/compaction-basic) (`waterfall`) | [`compaction-image-offload`](../packages/compaction/compaction-image-offload) | | `connection/request` | `waterfall` | [`packages/client/connection/src/index.ts:62`](../packages/client/connection/src/index.ts) | `connection` (`waterfall`) | - | | `cordis/dynamic-package` | `emit` | [`packages/extensions/cordis-host-runner/src/types.ts:380`](../packages/extensions/cordis-host-runner/src/types.ts) | [`cordis-host-runner`](../packages/extensions/cordis-host-runner) (`emit`) | `remotes` | | `cordis/dynamic-retract` | `emit` | [`packages/extensions/cordis-host-runner/src/types.ts:386`](../packages/extensions/cordis-host-runner/src/types.ts) | [`cordis-host-runner`](../packages/extensions/cordis-host-runner) (`emit`) | `remotes` | @@ -51,31 +51,31 @@ | `hmr/change` | `emit` | [`packages/boot/hmr/src/index.ts:30`](../packages/boot/hmr/src/index.ts) | [`hmr`](../packages/boot/hmr) (`emit`) | - | | `hmr/reload` | `emit` | [`packages/boot/hmr/src/index.ts:35`](../packages/boot/hmr/src/index.ts) | [`hmr`](../packages/boot/hmr) (`emit`) | - | | `llm/adapters-updated` | `emit` | [`packages/llm/llm/src/types.ts:23`](../packages/llm/llm/src/types.ts) | [`llm`](../packages/llm/llm) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`llm`](../packages/llm/llm), `remotes` | -| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:72`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) | +| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:73`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) | | `permission-presets/catalog-changed` | `emit` | [`packages/interaction/permission-presets/src/types.ts:44`](../packages/interaction/permission-presets/src/types.ts) | [`permission-presets`](../packages/interaction/permission-presets) (`events.dispatch`) | `remotes` | | `plugin-manager/changed` | `emit` | [`packages/boot/plugin-manager/src/types.ts:223`](../packages/boot/plugin-manager/src/types.ts) | [`plugin-manager`](../packages/boot/plugin-manager) (`emit`) | `remotes` | | `plugin-manager/install-log` | `emit` | [`packages/boot/plugin-manager/src/types.ts:229`](../packages/boot/plugin-manager/src/types.ts) | [`plugin-manager`](../packages/boot/plugin-manager) (`emit`) | `remotes` | | `plugin-manager/install-state` | `emit` | [`packages/boot/plugin-manager/src/types.ts:236`](../packages/boot/plugin-manager/src/types.ts) | [`plugin-manager`](../packages/boot/plugin-manager) (`emit`) | `remotes` | | `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - | -| `session/created` | `emit` | [`packages/core/session/src/index.ts:50`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), `session-controller`, [`session-log-deepseek`](../packages/session/session-log-deepseek), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | -| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:60`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `file-upload`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `session/event` | `emit` | [`packages/core/session/src/index.ts:72`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:81`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-telemetry`](../packages/session/session-telemetry) | +| `session/created` | `emit` | [`packages/core/session/src/index.ts:53`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), `session-controller`, [`session-log-deepseek`](../packages/session/session-log-deepseek), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | +| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:63`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `file-upload`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`workspace-changes`](../packages/deliverables/workspace-changes) | +| `session/event` | `emit` | [`packages/core/session/src/index.ts:75`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-changes`](../packages/deliverables/workspace-changes) | +| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:84`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-telemetry`](../packages/session/session-telemetry) | | `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:105`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `remotes` | | `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:92`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) | | `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:296`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - | -| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:171`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), `server`, [`subagent`](../packages/subagent/subagent) | -| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:145`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:151`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:162`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`subagent`](../packages/subagent/subagent) | +| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:173`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), `server`, [`subagent`](../packages/subagent/subagent) | +| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:147`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:153`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:164`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`subagent`](../packages/subagent/subagent) | | `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-presets`](../packages/preset/agent-presets), `browser-use-runtime`, [`session-reference`](../packages/context/session-reference), [`system-prompt`](../packages/core/system-prompt) | | `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - | -| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:201`](../packages/core/tools/src/index.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) | -| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:157`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` | -| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:169`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) | -| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:146`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) | -| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:183`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) | -| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:191`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), [`subagent-in-process-driver`](../packages/subagent/subagent-in-process-driver), [`tool-present`](../packages/deliverables/tool-present) | +| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:208`](../packages/core/tools/src/index.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) | +| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:164`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` | +| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:176`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) | +| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:153`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) | +| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:190`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) | +| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:198`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), [`subagent-in-process-driver`](../packages/subagent/subagent-in-process-driver), [`tool-present`](../packages/deliverables/tool-present) | | `user-questions/request` | `waterfall` | [`packages/interaction/user-questions/src/types.ts:88`](../packages/interaction/user-questions/src/types.ts) | [`user-questions`](../packages/interaction/user-questions) (`waterfall`) | `remotes` | | `webserver/index-inject` | `emit` | [`packages/host/webserver/src/index.ts:34`](../packages/host/webserver/src/index.ts) | `webserver` (`emit`) | `connection`, `inspector`, `modules`, `ui-sidebar-documentpreview` | | `workflow/agent-end` | `emit` | [`packages/workflow/workflow/src/index.ts:79`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) | diff --git a/docs/module-graph.i18n.yaml b/docs/module-graph.i18n.yaml index 4a2feec24a..5c4c75fd7e 100644 --- a/docs/module-graph.i18n.yaml +++ b/docs/module-graph.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/module-graph.md -module-graph.md: 90c9601b329daa91f21713a20cf499c9937e6d34 -module-graph.zh.md: 19e6bd1b942ae3319f137b7528fea4b69383d0aa +module-graph.md: 5471a7a6160dec338f5b1e542cd14483f1325f13 +module-graph.zh.md: 9214a63680f28ee70830ca0ed23f33204e3cb116 diff --git a/docs/module-graph.md b/docs/module-graph.md index 90c9601b32..5471a7a616 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -324,6 +324,7 @@ flowchart TD pkg_session_format_v0_to_v1["session-format-v0-to-v1"] pkg_session_format_v1_to_v2["session-format-v1-to-v2"] pkg_session_format_v2_to_v3["session-format-v2-to-v3"] + pkg_session_format_v3_to_v4["session-format-v3-to-v4"] pkg_session_log_deepseek["session-log-deepseek"] pkg_session_persistence["session-persistence"] pkg_session_persistence_jsonl["session-persistence-jsonl"] @@ -1392,6 +1393,7 @@ flowchart TD | [`session-format-v0-to-v1`](../packages/session/session-format-v0-to-v1) | `session` | — | | [`session-format-v1-to-v2`](../packages/session/session-format-v1-to-v2) | `session` | — | | [`session-format-v2-to-v3`](../packages/session/session-format-v2-to-v3) | `session` | — | +| [`session-format-v3-to-v4`](../packages/session/session-format-v3-to-v4) | `session` | — | | [`storage`](../packages/storage/storage) | `storage` | — | | [`win32-process`](../packages/subprocess/win32-process) | `subprocess` | — | | [`llm-mock-server`](../packages/test-support/llm-mock-server) | `test-support` | — | diff --git a/docs/module-graph.zh.md b/docs/module-graph.zh.md index 19e6bd1b94..9214a63680 100644 --- a/docs/module-graph.zh.md +++ b/docs/module-graph.zh.md @@ -326,6 +326,7 @@ flowchart TD pkg_session_format_v0_to_v1["session-format-v0-to-v1"] pkg_session_format_v1_to_v2["session-format-v1-to-v2"] pkg_session_format_v2_to_v3["session-format-v2-to-v3"] + pkg_session_format_v3_to_v4["session-format-v3-to-v4"] pkg_session_log_deepseek["session-log-deepseek"] pkg_session_persistence["session-persistence"] pkg_session_persistence_jsonl["session-persistence-jsonl"] @@ -1394,6 +1395,7 @@ flowchart TD | [`session-format-v0-to-v1`](../packages/session/session-format-v0-to-v1) | `session` | — | | [`session-format-v1-to-v2`](../packages/session/session-format-v1-to-v2) | `session` | — | | [`session-format-v2-to-v3`](../packages/session/session-format-v2-to-v3) | `session` | — | +| [`session-format-v3-to-v4`](../packages/session/session-format-v3-to-v4) | `session` | — | | [`storage`](../packages/storage/storage) | `storage` | — | | [`win32-process`](../packages/subprocess/win32-process) | `subprocess` | — | | [`llm-mock-server`](../packages/test-support/llm-mock-server) | `test-support` | — | diff --git a/docs/persistence-catalog.i18n.yaml b/docs/persistence-catalog.i18n.yaml index e215ea1a68..ae6c4b51eb 100644 --- a/docs/persistence-catalog.i18n.yaml +++ b/docs/persistence-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/persistence-catalog.md -persistence-catalog.md: be4a1f8760032d1c8cf526c879bb6b5b67531af2 -persistence-catalog.zh.md: 91ca2f7a03662b0ff1f5e42f084d49acdb172f13 +persistence-catalog.md: 43b4f86125847625026bd5619216ccdc7be926c1 +persistence-catalog.zh.md: c655d97086fa60630aa5dae1bf3f93be595f179b diff --git a/docs/persistence-catalog.md b/docs/persistence-catalog.md index be4a1f8760..43b4f86125 100644 --- a/docs/persistence-catalog.md +++ b/docs/persistence-catalog.md @@ -17,67 +17,68 @@ The [format references](persistence-changes/historical-formats/README.md) cover | Root | Kind | SHA-256 | Resolved type | |---|---|---|---| -| `SessionHeader` | header | `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` | [`packages/core/session/src/types.ts#SessionHeader`](#persistence-type-packagescoresessionsrctypestssessionheader) | -| `JsonlHeaderLine` | header | `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` | [`packages/session/session-persistence-jsonl/src/format.ts#HeaderLine`](#persistence-type-packagessessionsession-persistence-jsonlsrcformattsheaderline) | -| `SessionEventEnvelope` | envelope | `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` | [`SessionEventEnvelope`](#persistence-type-sessioneventenvelope) | -| `event:agent-preset/selected` | event | `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` | [`event:agent-preset/selected`](#persistence-type-eventagent-presetselected) | -| `event:agent/inbox/spliced` | event | `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` | [`event:agent/inbox/spliced`](#persistence-type-eventagentinboxspliced) | -| `event:approval/asked` | event | `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` | [`event:approval/asked`](#persistence-type-eventapprovalasked) | -| `event:approval/decided` | event | `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` | [`event:approval/decided`](#persistence-type-eventapprovaldecided) | -| `event:approval/policy` | event | `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` | [`event:approval/policy`](#persistence-type-eventapprovalpolicy) | -| `event:assistant/attempt` | event | `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` | [`event:assistant/attempt`](#persistence-type-eventassistantattempt) | -| `event:assistant/message` | event | `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` | [`event:assistant/message`](#persistence-type-eventassistantmessage) | -| `event:command/done` | event | `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` | [`event:command/done`](#persistence-type-eventcommanddone) | -| `event:command/run` | event | `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` | [`event:command/run`](#persistence-type-eventcommandrun) | -| `event:compaction/end` | event | `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` | [`event:compaction/end`](#persistence-type-eventcompactionend) | -| `event:compaction/prune` | event | `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` | [`event:compaction/prune`](#persistence-type-eventcompactionprune) | -| `event:compaction/start` | event | `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` | [`event:compaction/start`](#persistence-type-eventcompactionstart) | -| `event:compaction/summary` | event | `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` | [`event:compaction/summary`](#persistence-type-eventcompactionsummary) | -| `event:deliverables/presented` | event | `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` | [`event:deliverables/presented`](#persistence-type-eventdeliverablespresented) | -| `event:feedback/message-delete` | event | `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` | [`event:feedback/message-delete`](#persistence-type-eventfeedbackmessage-delete) | -| `event:feedback/message-put` | event | `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` | [`event:feedback/message-put`](#persistence-type-eventfeedbackmessage-put) | -| `event:feedback/record` | event | `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` | [`event:feedback/record`](#persistence-type-eventfeedbackrecord) | -| `event:goal/change` | event | `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` | [`event:goal/change`](#persistence-type-eventgoalchange) | -| `event:hook/invoked` | event | `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` | [`event:hook/invoked`](#persistence-type-eventhookinvoked) | -| `event:hook/result` | event | `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` | [`event:hook/result`](#persistence-type-eventhookresult) | -| `event:image/offload` | event | `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` | [`event:image/offload`](#persistence-type-eventimageoffload) | -| `event:llm/retry` | event | `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` | [`event:llm/retry`](#persistence-type-eventllmretry) | -| `event:llm/retry-started` | event | `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` | [`event:llm/retry-started`](#persistence-type-eventllmretry-started) | -| `event:model/selection` | event | `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` | [`event:model/selection`](#persistence-type-eventmodelselection) | -| `event:permission/preset` | event | `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` | [`event:permission/preset`](#persistence-type-eventpermissionpreset) | -| `event:plan/mode` | event | `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` | [`event:plan/mode`](#persistence-type-eventplanmode) | -| `event:request/context` | event | `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` | [`event:request/context`](#persistence-type-eventrequestcontext) | -| `event:request/header` | event | `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` | [`event:request/header`](#persistence-type-eventrequestheader) | -| `event:sandbox/mode` | event | `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` | [`event:sandbox/mode`](#persistence-type-eventsandboxmode) | -| `event:schedule/change` | event | `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` | [`event:schedule/change`](#persistence-type-eventschedulechange) | -| `event:session-log-deepseek/delivery-accepted` | event | `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` | [`event:session-log-deepseek/delivery-accepted`](#persistence-type-eventsession-log-deepseekdelivery-accepted) | -| `event:session/end-seed` | event | `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` | [`event:session/end-seed`](#persistence-type-eventsessionend-seed) | -| `event:session/title` | event | `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` | [`event:session/title`](#persistence-type-eventsessiontitle) | -| `event:session/title-llm-request` | event | `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` | [`event:session/title-llm-request`](#persistence-type-eventsessiontitle-llm-request) | -| `event:step/end` | event | `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` | [`event:step/end`](#persistence-type-eventstepend) | -| `event:step/start` | event | `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` | [`event:step/start`](#persistence-type-eventstepstart) | -| `event:subagent/catalog` | event | `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` | [`event:subagent/catalog`](#persistence-type-eventsubagentcatalog) | -| `event:subagent/descriptor` | event | `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` | [`event:subagent/descriptor`](#persistence-type-eventsubagentdescriptor) | -| `event:subagent/model-selection-policy` | event | `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` | [`event:subagent/model-selection-policy`](#persistence-type-eventsubagentmodel-selection-policy) | -| `event:system/message` | event | `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` | [`event:system/message`](#persistence-type-eventsystemmessage) | -| `event:team/member` | event | `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` | [`event:team/member`](#persistence-type-eventteammember) | -| `event:team/message/delivered` | event | `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` | [`event:team/message/delivered`](#persistence-type-eventteammessagedelivered) | -| `event:team/message/queued` | event | `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` | [`event:team/message/queued`](#persistence-type-eventteammessagequeued) | -| `event:team/task` | event | `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` | [`event:team/task`](#persistence-type-eventteamtask) | -| `event:todo/write` | event | `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` | [`event:todo/write`](#persistence-type-eventtodowrite) | -| `event:tool-workflow/agent-end` | event | `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` | [`event:tool-workflow/agent-end`](#persistence-type-eventtool-workflowagent-end) | -| `event:tool-workflow/agent-start` | event | `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` | [`event:tool-workflow/agent-start`](#persistence-type-eventtool-workflowagent-start) | -| `event:tool-workflow/run-end` | event | `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` | [`event:tool-workflow/run-end`](#persistence-type-eventtool-workflowrun-end) | -| `event:tool-workflow/run-start` | event | `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` | [`event:tool-workflow/run-start`](#persistence-type-eventtool-workflowrun-start) | -| `event:tool/call` | event | `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` | [`event:tool/call`](#persistence-type-eventtoolcall) | -| `event:tool/ptc-dispatch` | event | `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` | [`event:tool/ptc-dispatch`](#persistence-type-eventtoolptc-dispatch) | -| `event:tool/ptc-dispatch-start` | event | `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` | [`event:tool/ptc-dispatch-start`](#persistence-type-eventtoolptc-dispatch-start) | -| `event:tool/result` | event | `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` | [`event:tool/result`](#persistence-type-eventtoolresult) | -| `event:turn/end` | event | `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` | [`event:turn/end`](#persistence-type-eventturnend) | -| `event:turn/start` | event | `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` | [`event:turn/start`](#persistence-type-eventturnstart) | -| `event:user/message` | event | `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` | [`event:user/message`](#persistence-type-eventusermessage) | -| `event:web/deepseek-search-llm-request` | event | `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` | [`event:web/deepseek-search-llm-request`](#persistence-type-eventwebdeepseek-search-llm-request) | -| `event:workspace/changes` | event | `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | [`event:workspace/changes`](#persistence-type-eventworkspacechanges) | +| `SessionHeader` | header | `1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445` | [`SessionHeader`](#persistence-type-sha256-1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445) | +| `JsonlHeaderLine` | header | `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` | [`HeaderLine`](#persistence-type-sha256-18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f) | +| `SessionEventEnvelope` | envelope | `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` | [`union (3 variants)`](#persistence-type-sha256-5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc) | +| `event:agent-preset/selected` | event | `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` | [`{ type: "agent-preset/selected" }`](#persistence-type-sha256-a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b) | +| `event:agent/inbox/spliced` | event | `1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c` | [`{ type: "agent/inbox/spliced" }`](#persistence-type-sha256-1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c) | +| `event:approval/asked` | event | `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` | [`{ type: "approval/asked" }`](#persistence-type-sha256-3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1) | +| `event:approval/decided` | event | `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` | [`{ type: "approval/decided" }`](#persistence-type-sha256-bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3) | +| `event:approval/policy` | event | `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` | [`{ type: "approval/policy" }`](#persistence-type-sha256-26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78) | +| `event:assistant/attempt` | event | `15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4` | [`{ type: "assistant/attempt" }`](#persistence-type-sha256-15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4) | +| `event:assistant/message` | event | `1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625` | [`{ type: "assistant/message" }`](#persistence-type-sha256-1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625) | +| `event:command/done` | event | `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` | [`{ type: "command/done" }`](#persistence-type-sha256-15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff) | +| `event:command/run` | event | `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` | [`{ type: "command/run" }`](#persistence-type-sha256-37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006) | +| `event:compaction/end` | event | `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` | [`{ type: "compaction/end" }`](#persistence-type-sha256-b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d) | +| `event:compaction/prune` | event | `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` | [`{ type: "compaction/prune" }`](#persistence-type-sha256-7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04) | +| `event:compaction/start` | event | `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` | [`{ type: "compaction/start" }`](#persistence-type-sha256-db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965) | +| `event:compaction/summary` | event | `e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602` | [`{ type: "compaction/summary" }`](#persistence-type-sha256-e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602) | +| `event:deliverables/presented` | event | `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` | [`{ type: "deliverables/presented" }`](#persistence-type-sha256-13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176) | +| `event:developer/message` | event | `eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80` | [`{ type: "developer/message" }`](#persistence-type-sha256-eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80) | +| `event:feedback/message-delete` | event | `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` | [`{ type: "feedback/message-delete" }`](#persistence-type-sha256-3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796) | +| `event:feedback/message-put` | event | `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` | [`{ type: "feedback/message-put" }`](#persistence-type-sha256-b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf) | +| `event:feedback/record` | event | `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` | [`{ type: "feedback/record" }`](#persistence-type-sha256-b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8) | +| `event:goal/change` | event | `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` | [`{ type: "goal/change" }`](#persistence-type-sha256-763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d) | +| `event:hook/invoked` | event | `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` | [`{ type: "hook/invoked" }`](#persistence-type-sha256-8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0) | +| `event:hook/result` | event | `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` | [`{ type: "hook/result" }`](#persistence-type-sha256-e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4) | +| `event:image/offload` | event | `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` | [`{ type: "image/offload" }`](#persistence-type-sha256-b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e) | +| `event:llm/retry` | event | `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` | [`{ type: "llm/retry" }`](#persistence-type-sha256-525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336) | +| `event:llm/retry-started` | event | `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` | [`{ type: "llm/retry-started" }`](#persistence-type-sha256-48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3) | +| `event:model/selection` | event | `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` | [`{ type: "model/selection" }`](#persistence-type-sha256-35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc) | +| `event:permission/preset` | event | `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` | [`{ type: "permission/preset" }`](#persistence-type-sha256-5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b) | +| `event:plan/mode` | event | `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` | [`{ type: "plan/mode" }`](#persistence-type-sha256-a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f) | +| `event:request/context` | event | `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` | [`{ type: "request/context" }`](#persistence-type-sha256-37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf) | +| `event:request/header` | event | `4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41` | [`{ type: "request/header" }`](#persistence-type-sha256-4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41) | +| `event:sandbox/mode` | event | `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` | [`{ type: "sandbox/mode" }`](#persistence-type-sha256-516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415) | +| `event:schedule/change` | event | `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` | [`{ type: "schedule/change" }`](#persistence-type-sha256-2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42) | +| `event:session-log-deepseek/delivery-accepted` | event | `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` | [`{ type: "session-log-deepseek/delivery-accepted" }`](#persistence-type-sha256-d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9) | +| `event:session/end-seed` | event | `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` | [`{ type: "session/end-seed" }`](#persistence-type-sha256-5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e) | +| `event:session/title` | event | `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` | [`{ type: "session/title" }`](#persistence-type-sha256-1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5) | +| `event:session/title-llm-request` | event | `fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d` | [`{ type: "session/title-llm-request" }`](#persistence-type-sha256-fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d) | +| `event:step/end` | event | `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` | [`{ type: "step/end" }`](#persistence-type-sha256-e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05) | +| `event:step/start` | event | `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` | [`{ type: "step/start" }`](#persistence-type-sha256-4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986) | +| `event:subagent/catalog` | event | `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` | [`{ type: "subagent/catalog" }`](#persistence-type-sha256-ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871) | +| `event:subagent/descriptor` | event | `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` | [`{ type: "subagent/descriptor" }`](#persistence-type-sha256-b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5) | +| `event:subagent/model-selection-policy` | event | `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` | [`{ type: "subagent/model-selection-policy" }`](#persistence-type-sha256-a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc) | +| `event:system/message` | event | `69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1` | [`{ type: "system/message" }`](#persistence-type-sha256-69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1) | +| `event:team/member` | event | `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` | [`{ type: "team/member" }`](#persistence-type-sha256-4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc) | +| `event:team/message/delivered` | event | `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` | [`{ type: "team/message/delivered" }`](#persistence-type-sha256-48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb) | +| `event:team/message/queued` | event | `21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d` | [`{ type: "team/message/queued" }`](#persistence-type-sha256-21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d) | +| `event:team/task` | event | `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` | [`{ type: "team/task" }`](#persistence-type-sha256-d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a) | +| `event:todo/write` | event | `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` | [`{ type: "todo/write" }`](#persistence-type-sha256-b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26) | +| `event:tool-workflow/agent-end` | event | `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` | [`{ type: "tool-workflow/agent-end" }`](#persistence-type-sha256-babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7) | +| `event:tool-workflow/agent-start` | event | `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` | [`{ type: "tool-workflow/agent-start" }`](#persistence-type-sha256-5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627) | +| `event:tool-workflow/run-end` | event | `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` | [`{ type: "tool-workflow/run-end" }`](#persistence-type-sha256-42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f) | +| `event:tool-workflow/run-start` | event | `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` | [`{ type: "tool-workflow/run-start" }`](#persistence-type-sha256-c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058) | +| `event:tool/call` | event | `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` | [`{ type: "tool/call" }`](#persistence-type-sha256-3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48) | +| `event:tool/ptc-dispatch` | event | `100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163` | [`{ type: "tool/ptc-dispatch" }`](#persistence-type-sha256-100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163) | +| `event:tool/ptc-dispatch-start` | event | `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` | [`{ type: "tool/ptc-dispatch-start" }`](#persistence-type-sha256-ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93) | +| `event:tool/result` | event | `7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397` | [`{ type: "tool/result" }`](#persistence-type-sha256-7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397) | +| `event:turn/end` | event | `0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce` | [`{ type: "turn/end" }`](#persistence-type-sha256-0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce) | +| `event:turn/start` | event | `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` | [`{ type: "turn/start" }`](#persistence-type-sha256-aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8) | +| `event:user/message` | event | `3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761` | [`{ type: "user/message" }`](#persistence-type-sha256-3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761) | +| `event:web/deepseek-search-llm-request` | event | `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` | [`{ type: "web/deepseek-search-llm-request" }`](#persistence-type-sha256-cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331) | +| `event:workspace/changes` | event | `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | [`{ type: "workspace/changes" }`](#persistence-type-sha256-e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72) | ## Event envelope @@ -93,6 +94,7 @@ export type SessionEventType = keyof SessionEventMap */ export type SurfaceEventType = | 'system/message' + | 'developer/message' | 'user/message' | 'assistant/message' | 'tool/result' @@ -153,7 +155,7 @@ export type SessionEvent = { }[T] ``` -Sources: [`packages/core/session/src/types.ts:409`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:417`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:439`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:470`](../packages/core/session/src/types.ts) +Sources: [`packages/core/session/src/types.ts:431`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:439`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:462`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:493`](../packages/core/session/src/types.ts) ## Events @@ -263,7 +265,7 @@ Source: [`packages/interaction/user-approval/src/types.ts:55`](../packages/inter } ``` -Source: [`packages/interaction/user-approval/src/index.ts:33`](../packages/interaction/user-approval/src/index.ts) +Source: [`packages/interaction/user-approval/src/index.ts:40`](../packages/interaction/user-approval/src/index.ts) ### `assistant/*` @@ -280,7 +282,7 @@ Source: [`packages/interaction/user-approval/src/index.ts:33`](../packages/inter 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[] } ``` -Source: [`packages/core/session/src/types.ts:335`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) @@ -310,7 +312,7 @@ Source: [`packages/core/session/src/types.ts:335`](../packages/core/session/src/ Types: [TokenUsage](subsystems/llm-streaming.md) -Source: [`packages/core/session/src/types.ts:321`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) ### `command/*` @@ -481,6 +483,25 @@ Types: [PresentedFile](subsystems/deliverables.md) · [ToolCallId](subsystems/co Source: [`packages/deliverables/tool-present/src/types.ts:15`](../packages/deliverables/tool-present/src/types.ts) +### `developer/*` + + + +#### `developer/message` — surface + +```ts persistence-catalog +/** An incremental agent session change admitted at the named turn and step. */ +'developer/message': { + turn: number + step: number + message: DeveloperMessage + /** Earlier request/header defining every tool addition; required exactly when additions are present. */ + headerSeq?: SessionSeq +} +``` + +Source: [`packages/core/session/src/types.ts:311`](../packages/core/session/src/types.ts) + ### `feedback/*` @@ -676,7 +697,7 @@ Source: [`packages/interaction/permission-presets/src/index.ts:57`](../packages/ 'plan/mode': { active: boolean } ``` -Source: [`packages/plan/plan-mode/src/index.ts:47`](../packages/plan/plan-mode/src/index.ts) +Source: [`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts) ### `request/*` @@ -694,7 +715,7 @@ Source: [`packages/plan/plan-mode/src/index.ts:47`](../packages/plan/plan-mode/s 'request/context': RequestContext ``` -Source: [`packages/core/session/src/types.ts:382`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:402`](../packages/core/session/src/types.ts) @@ -713,7 +734,7 @@ Source: [`packages/core/session/src/types.ts:382`](../packages/core/session/src/ } ``` -Source: [`packages/core/session/src/types.ts:370`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:390`](../packages/core/session/src/types.ts) ### `sandbox/*` @@ -764,19 +785,21 @@ Source: [`packages/schedule/schedule/src/types.ts:219`](../packages/schedule/sch ```ts persistence-catalog /** - * Marks the end of a constructor seed. Events before it have smaller seq - * values and came from the seed (resume, fork, or replay); this lifecycle - * produced none of them. This log-only event is the durable projection of - * {@link Session.firstLiveSeq}. + * Separates inherited or restored history from later lifecycle-owned work. + * This log-only marker need not be at {@link Session.firstLiveSeq}: a fork + * seed can already contain its tagged marker and child-owned synthetic + * closers before construction. * * A fresh fork child owns one `{ inherited: true }` marker at its exact * inherited-prefix cut, even when that prefix ends in an ancestor marker. - * The last tagged marker is the current Session's cut; untagged markers keep - * ordinary restore and replay lifecycle boundaries. + * `buildForkSeed` appends that marker before any synthetic closers; the + * `Session` constructor supplies it when given only the inherited prefix. + * The last tagged marker is the current Session's cut; untagged markers + * keep ordinary restore and replay lifecycle boundaries. * - * `Session`'s constructor is the only legitimate writer. The invariant - * companion deliberately constrains nothing here, so a plugin appending one - * would silently classify every live bracket before it as seed history. + * Only the `Session` constructor and `buildForkSeed` may create this marker. + * The invariant companion deliberately constrains nothing here, so a plugin + * appending one would silently classify every live bracket before it as seed history. * * An owner of a standalone open/close bracket (`compaction/start` … * `compaction/end`) reads it because seed history and live work are otherwise @@ -788,7 +811,7 @@ Source: [`packages/schedule/schedule/src/types.ts:219`](../packages/schedule/sch 'session/end-seed': { inherited?: true } ``` -Source: [`packages/core/session/src/types.ts:405`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:427`](../packages/core/session/src/types.ts) @@ -817,7 +840,7 @@ Source: [`packages/session/session-title/src/index.ts:77`](../packages/session/s Types: [SessionTitleLlmRequestEventData](subsystems/session-title.md) -Source: [`packages/session/session-title-llm/src/index.ts:45`](../packages/session/session-title-llm/src/index.ts) +Source: [`packages/session/session-title-llm/src/index.ts:52`](../packages/session/session-title-llm/src/index.ts) ### `session-log-deepseek/*` @@ -850,7 +873,7 @@ Source: [`packages/session/session-log-deepseek/src/types.ts:81`](../packages/se 'step/end': { turn: number; step: number } ``` -Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:301`](../packages/core/session/src/types.ts) @@ -861,7 +884,7 @@ Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/ 'step/start': { turn: number; step: number } ``` -Source: [`packages/core/session/src/types.ts:287`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:299`](../packages/core/session/src/types.ts) ### `subagent/*` @@ -937,7 +960,7 @@ Source: [`packages/subagent/tool-subagent/src/model-selection-state.ts:17`](../p 'system/message': { turn: number; step: number; message: SystemMessage } ``` -Source: [`packages/core/session/src/types.ts:310`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:330`](../packages/core/session/src/types.ts) ### `team/*` @@ -1030,7 +1053,7 @@ Source: [`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/s Types: [ToolCallId](subsystems/core.md) -Source: [`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:361`](../packages/core/session/src/types.ts) @@ -1104,14 +1127,14 @@ Source: [`packages/core/tools/src/types.ts:42`](../packages/core/tools/src/types message: ToolResultMessage /** * Optional failure identity and raw user-facing reason, outside model content; - * allowed only when the tool-result block has `isError: true`. + * allowed only when the message has `isError: true`. */ error?: { name: string; code: string; reason?: string } meta?: JsonValue } ``` -Source: [`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:375`](../packages/core/session/src/types.ts) ### `tool-workflow/*` @@ -1191,7 +1214,7 @@ Source: [`packages/workflow/tool-workflow/src/types.ts:47`](../packages/workflow Types: [TurnEndReason](subsystems/session.md) -Source: [`packages/core/session/src/types.ts:285`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:297`](../packages/core/session/src/types.ts) @@ -1207,7 +1230,7 @@ Source: [`packages/core/session/src/types.ts:285`](../packages/core/session/src/ 'turn/start': { turn: number } ``` -Source: [`packages/core/session/src/types.ts:276`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:288`](../packages/core/session/src/types.ts) ### `user/*` @@ -1226,7 +1249,7 @@ Source: [`packages/core/session/src/types.ts:276`](../packages/core/session/src/ 'user/message': UserMessage ``` -Source: [`packages/core/session/src/types.ts:297`](../packages/core/session/src/types.ts) +Source: [`packages/core/session/src/types.ts:309`](../packages/core/session/src/types.ts) ### `web/*` @@ -1262,39 +1285,7 @@ Source: [`packages/deliverables/workspace-changes/src/types.ts:106`](../packages Each definition appears once. References preserve sharing and recursion; the digest beside a definition includes its complete reachable structure. Source names and locations identify its declarations but are excluded from its digest. - - -### `0` - -SHA-256: `93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35` - -`0` - - - -### `1` - -SHA-256: `f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d` - -`1` - - - -### `2` - -SHA-256: `a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80` - -`2` - - - -### `3` - -SHA-256: `137ac60e26bcb192210d9a32a704b73b0924ed34019323defa1b787be95bd45e` - -`3` - - + ### `"aborted"` @@ -1302,7 +1293,7 @@ SHA-256: `1e0b0b66b6f0c53fc72e52289d06b4708d776f1ca9df4c86a22bff621d403cf0` `"aborted"` - + ### `"active"` @@ -1310,7 +1301,7 @@ SHA-256: `c8e6f48878cc2a2f0dc59682280d81f407943fb503f32c64bf9ff3d9393c3eff` `"active"` - + ### `"after"` @@ -1318,7 +1309,7 @@ SHA-256: `5b232a9b9bfcc0fc6794dab7865bcf203a65785c5de5aa647a51228bff628413` `"after"` - + ### `"agent-instructions"` @@ -1326,7 +1317,7 @@ SHA-256: `fbd2c74b346a1595b376139c587fadd23e4a21acc9c0abce342975b6cfc60986` `"agent-instructions"` - + ### `"agent-message"` @@ -1334,7 +1325,7 @@ SHA-256: `82470020b5bfcb1a843e2aa05602af7d37df99e82d01f015c7c589ba054fd89d` `"agent-message"` - + ### `"agent-preset/selected"` @@ -1342,7 +1333,7 @@ SHA-256: `557e148d30b79ee48645850832b30c717d7c3b64641deb5d6133b8b4e91ee0b8` `"agent-preset/selected"` - + ### `"agent/inbox/spliced"` @@ -1350,7 +1341,7 @@ SHA-256: `829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809` `"agent/inbox/spliced"` - + ### `"allowed-once"` @@ -1358,7 +1349,7 @@ SHA-256: `811229eedcec57979dbadca7dbea832a59f8580cff30cb217fca5e2da16314bd` `"allowed-once"` - + ### `"always"` @@ -1366,7 +1357,7 @@ SHA-256: `142c37d302aa22a0a57915b5255939d3ca91c1811ca13fddcf84cf76ea00758a` `"always"` - + ### `"append"` @@ -1374,7 +1365,7 @@ SHA-256: `e438a9d4fb883b3e4a8d9fc8913aa1550ed50eb384bfbf943100a5605b537498` `"append"` - + ### `"approval/asked"` @@ -1382,7 +1373,7 @@ SHA-256: `cd186c309e2bef305705e1d324139240f5e681f4f6a957d6a25b0225f65560df` `"approval/asked"` - + ### `"approval/decided"` @@ -1390,7 +1381,7 @@ SHA-256: `378f90f9f6022a0991928a1eaf7991094ea1920fe89a9248358a1da106e1a970` `"approval/decided"` - + ### `"approval/policy"` @@ -1398,7 +1389,7 @@ SHA-256: `36d6a9a871d949ea4f3edd919d81d66aa69218bebef38899d2a1282c39420a1f` `"approval/policy"` - + ### `"ask"` @@ -1406,7 +1397,7 @@ SHA-256: `9e07693fd7cd9babe0688c22c986e4d519ae1c0e40eeea13b2dc583bed2abc86` `"ask"` - + ### `"assistant"` @@ -1414,7 +1405,7 @@ SHA-256: `95c0e88fcf0bafb2087f912ad9e2369de6ae6530cc0c4c2772c96205b57f7f60` `"assistant"` - + ### `"assistant/attempt"` @@ -1422,7 +1413,7 @@ SHA-256: `e95f957154b2b1b58692af53d4131180b6dd19e2264869f876dbaa959991494e` `"assistant/attempt"` - + ### `"assistant/message"` @@ -1430,7 +1421,7 @@ SHA-256: `6ab45ac76839722df912f3ba50f1c6b41f2d614bde11f1aabfae04117ccdc80d` `"assistant/message"` - + ### `"at"` @@ -1438,7 +1429,7 @@ SHA-256: `17aae616ef020b8b9f011ec398ec935450fb06d3e2a0722c456f63aeaf5ff728` `"at"` - + ### `"block"` @@ -1446,7 +1437,7 @@ SHA-256: `1e346446e183ee76f48d7994c97ecb302bddc682abb60b8a10ea0bb26223a69c` `"block"` - + ### `"block-end"` @@ -1454,7 +1445,7 @@ SHA-256: `eefbea819caeeea91ccb02dfafc16c68dd7f961cf9c1b2be25a2084509cf5c5a` `"block-end"` - + ### `"block-start"` @@ -1462,7 +1453,7 @@ SHA-256: `cbca49bde16b656d5b8fbe4a8a507769f7b594c6287782b809c03814941bc5e3` `"block-start"` - + ### `"blocked"` @@ -1470,15 +1461,7 @@ SHA-256: `254dce209e735f9cb6f6b7aec0354712b1611759ec02af4d35a96f2081e666f6` `"blocked"` - - -### `boolean` - -SHA-256: `aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877` - -`boolean` - - + ### `"canceled"` @@ -1486,7 +1469,7 @@ SHA-256: `d4e4d575abeb4b72d616dc65c17ac0eaa943cc135609395044c38d5afcb10e31` `"canceled"` - + ### `"cancelled"` @@ -1494,7 +1477,7 @@ SHA-256: `2142e391b9ccb60d487afcf373ce74db98d952f69e8289eddb352a7e16e996c5` `"cancelled"` - + ### `"catalog"` @@ -1502,7 +1485,7 @@ SHA-256: `aec150797b655c5f15ebb7a501454b0c208fbaccec9ace49d7de2171fc02f47d` `"catalog"` - + ### `"change"` @@ -1510,7 +1493,7 @@ SHA-256: `f789af5ab844827eb5a4f357c0afae1eeed108c6c22d8ca1a56e586b349a7c85` `"change"` - + ### `"chunk"` @@ -1518,7 +1501,7 @@ SHA-256: `14230f9b8b5797bb7e8c621fa636531cfbde2ffba1ef5f1fd058216ff21952a0` `"chunk"` - + ### `"claude-code"` @@ -1526,7 +1509,7 @@ SHA-256: `aff60ef947c18b012644852bdd0d5bfe72065e061dd563787c76c646b4a10f6b` `"claude-code"` - + ### `"clear"` @@ -1534,7 +1517,7 @@ SHA-256: `e7e154d47d5fbc5366330fb4dade1f108c6dfe4335044d21ded14b7bf1dce084` `"clear"` - + ### `"codex"` @@ -1542,7 +1525,7 @@ SHA-256: `15495614ccfa9cbdeefb0ec2abd76406435f4c6ff3dae42acae8e09ef42025c9` `"codex"` - + ### `"command/done"` @@ -1550,7 +1533,7 @@ SHA-256: `8cdd3fdd295cee53035de16a1b23411716f75e9f994fe9510cac5d7fef605c76` `"command/done"` - + ### `"command/run"` @@ -1558,7 +1541,15 @@ SHA-256: `f1996af2602e6f62b5ab179ca5c4af00d8753938b74cc6ef102de09e99e74a7e` `"command/run"` - + + +### `"compact-checkpoint"` + +SHA-256: `6b23ed9ce1b397e602788dbe033693bf97642a69e23fcab1cc45bf6f13b6d619` + +`"compact-checkpoint"` + + ### `"compaction/end"` @@ -1566,7 +1557,7 @@ SHA-256: `1986c2664009c99155e44795676c887fa67f7c55cd2d5e6b648ff763e0ab033a` `"compaction/end"` - + ### `"compaction/prune"` @@ -1574,7 +1565,7 @@ SHA-256: `10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe` `"compaction/prune"` - + ### `"compaction/start"` @@ -1582,7 +1573,7 @@ SHA-256: `e2d0367e5716bc188435e51718ebff8ce873190625fa93b1c5331102d98758fa` `"compaction/start"` - + ### `"compaction/summary"` @@ -1590,7 +1581,7 @@ SHA-256: `ef4f00923b9edbae15c7ef05320280bf61147ca17146cf59690359bfd5e5da45` `"compaction/summary"` - + ### `"complete"` @@ -1598,7 +1589,7 @@ SHA-256: `d9196086e41e4dd5c2ce87f5c25529c8112a1731d258cf0728747d41a9ee3241` `"complete"` - + ### `"completed"` @@ -1606,7 +1597,7 @@ SHA-256: `1ebc6f9ff3aa9e3a38f8695f49bacdab1f8b7a3832741853ca46f40af56ccd01` `"completed"` - + ### `"continuable"` @@ -1614,7 +1605,15 @@ SHA-256: `e5d3828df1ec3e2a66879de0659e0f4866d9cfffc00825ee731a66f8a0c03d98` `"continuable"` - + + +### `"cordis-host-runner"` + +SHA-256: `c5687b1313206a6ff334066047b6a0681611467dc4df8c5a8e71d0b6df39311f` + +`"cordis-host-runner"` + + ### `"create"` @@ -1622,7 +1621,7 @@ SHA-256: `7624ca28c61ca0eaa4f015140f3cea6e0c16cce2f2960fab5f531203d253903e` `"create"` - + ### `"danger-full-access"` @@ -1630,7 +1629,7 @@ SHA-256: `18fce9540bb20897a66275499faee6b8296c97e9901fa1ff45a191772448ad1a` `"danger-full-access"` - + ### `"delegation"` @@ -1638,7 +1637,7 @@ SHA-256: `76632533f67879dcb346fcae640540dbc89b2472b0bce88c59f7e48fc5c0e668` `"delegation"` - + ### `"delete"` @@ -1646,7 +1645,7 @@ SHA-256: `d0fbb0ca1bbba059830826f33f801da1aced35a2504376d61e020bdfec8d50c0` `"delete"` - + ### `"deleted"` @@ -1654,7 +1653,7 @@ SHA-256: `e7e8f1318170b8284f16ab45a557afd4675c96071c0f2a456636481dab20b427` `"deleted"` - + ### `"deliverables/presented"` @@ -1662,7 +1661,23 @@ SHA-256: `1a2718b00937b236a0d0910ef5dab2f9f8b65e4bde410cc21f15fbbf29f584d3` `"deliverables/presented"` - + + +### `"developer"` + +SHA-256: `589d0d91239681f89ee485459dc8c2f73ea47183b5534289d966637024a2c35d` + +`"developer"` + + + +### `"developer/message"` + +SHA-256: `1379f0b72275994d20f1ddca2d60a96ab16ec80397ca9f1af21bdc67ba5c269c` + +`"developer/message"` + + ### `"dispatch"` @@ -1670,7 +1685,7 @@ SHA-256: `26c879bdd130e8b8683a6ce588414fad2244783d6573ca399fa0de184a2b0bb1` `"dispatch"` - + ### `"disposed"` @@ -1678,7 +1693,15 @@ SHA-256: `b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751` `"disposed"` - + + +### `"dsh-session-title-llm"` + +SHA-256: `23af3759678a30de1d11d946772da8c051c63caa67997c5da05d30d7a9fe8a97` + +`"dsh-session-title-llm"` + + ### `"edit"` @@ -1686,7 +1709,7 @@ SHA-256: `ad22a5ca5bbaab2e1440779cd3648e85ddfc6f73b5207394eda699555cf31430` `"edit"` - + ### `"error"` @@ -1694,169 +1717,3693 @@ SHA-256: `a2be0f0cb59f0d4a06557d45847d1938aced238baa77a6da416e590b8b958553` `"error"` - + -### `event:agent-preset/selected` +### `"every"` -SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` +SHA-256: `e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87` + +`"every"` + + + +### `"failed"` + +SHA-256: `b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420` + +`"failed"` + + + +### `"fallback"` + +SHA-256: `d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c` + +`"fallback"` + + + +### `"feedback/message-delete"` + +SHA-256: `44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e` + +`"feedback/message-delete"` + + + +### `"feedback/message-put"` + +SHA-256: `6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8` + +`"feedback/message-put"` + + + +### `"feedback/record"` + +SHA-256: `c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954` + +`"feedback/record"` + + + +### `"file"` + +SHA-256: `277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9` + +`"file"` + + + +### `"finish"` + +SHA-256: `bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd` + +`"finish"` + + + +### `"fork"` + +SHA-256: `2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863` + +`"fork"` + + + +### `"forked"` + +SHA-256: `b2245a906e13aa94f2d3cc6cf7b04cfa0267f7b7f4d468de1b00b1a314e54626` + +`"forked"` + + + +### `"fresh"` + +SHA-256: `dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d` + +`"fresh"` + + + +### `"goal"` + +SHA-256: `b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602` + +`"goal"` + + + +### `"goal/change"` + +SHA-256: `237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163` + +`"goal/change"` + + + +### `"hook"` + +SHA-256: `dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc` + +`"hook"` + + + +### `"hook/invoked"` + +SHA-256: `b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611` + +`"hook/invoked"` + + + +### `"hook/result"` + +SHA-256: `a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2` + +`"hook/result"` + + + +### `"hooks-claude-code"` + +SHA-256: `a9059a81430b320792bbb7c2ee1f8f6c77ff71e40ee44c18aec72e157c522694` + +`"hooks-claude-code"` + + + +### `"hooks-codex"` + +SHA-256: `bb94f3217aa56c8876bbff0b8460d6a73cbead545659abb29e76cd0cf2cb92d6` + +`"hooks-codex"` + + + +### `"image"` + +SHA-256: `fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0` + +`"image"` + + + +### `"image/gif"` + +SHA-256: `de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048` + +`"image/gif"` + + + +### `"image/jpeg"` + +SHA-256: `3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004` + +`"image/jpeg"` + + + +### `"image/offload"` + +SHA-256: `9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49` + +`"image/offload"` + + + +### `"image/png"` + +SHA-256: `58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0` + +`"image/png"` + + + +### `"image/webp"` + +SHA-256: `ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8` + +`"image/webp"` + + + + + + + +### `"in-history"` + +SHA-256: `f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5` + +Sources: [`packages/llm/llm/src/types.ts:397`](../packages/llm/llm/src/types.ts) + +`"in-history"` + + + +### `"in_progress"` + +SHA-256: `94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378` + +`"in_progress"` + + + +### `"initial"` + +SHA-256: `e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c` + +`"initial"` + + + +### `"instruction-following"` + +SHA-256: `e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486` + +`"instruction-following"` + + + +### `"instructions"` + +SHA-256: `fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5` + +`"instructions"` + + + +### `"interrupted"` + +SHA-256: `69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199` + +`"interrupted"` + + + +### `"legacy"` + +SHA-256: `ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc` + +`"legacy"` + + + +### `"llm/retry"` + +SHA-256: `611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d` + +`"llm/retry"` + + + +### `"llm/retry-started"` + +SHA-256: `4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964` + +`"llm/retry-started"` + + + +### `"max-tokens"` + +SHA-256: `68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe` + +`"max-tokens"` + + + +### `"model"` + +SHA-256: `2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e` + +`"model"` + + + +### `"model-selection"` + +SHA-256: `9ac52f0f84fec2eb9f71c2937e497d759db5ca0da4836d93a679d113684141f2` + +`"model-selection"` + + + +### `"model/selection"` + +SHA-256: `1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2` + +`"model/selection"` + + + +### `"negative"` + +SHA-256: `b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5` + +`"negative"` + + + +### `"never"` + +SHA-256: `1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b` + +`"never"` + + + +### `"next-step"` + +SHA-256: `3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693` + +`"next-step"` + + + +### `"next-turn"` + +SHA-256: `62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd` + +`"next-turn"` + + + +### `"normal"` + +SHA-256: `3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79` + +`"normal"` + + + +### `"notice"` + +SHA-256: `e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367` + +`"notice"` + + + +### `"one-shot"` + +SHA-256: `d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2` + +`"one-shot"` + + + +### `"other"` + +SHA-256: `9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4` + +`"other"` + + + +### `"parent"` + +SHA-256: `e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732` + +`"parent"` + + + +### `"pause"` + +SHA-256: `1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721` + +`"pause"` + + + +### `"paused"` + +SHA-256: `c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943` + +`"paused"` + + + +### `"pending"` + +SHA-256: `234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85` + +`"pending"` + + + +### `"permission/preset"` + +SHA-256: `ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649` + +`"permission/preset"` + + + +### `"plan-mode"` + +SHA-256: `0fe52387f65052702ed9d7cd59db826468936595d1b3eec207e7a823adc719db` + +`"plan-mode"` + + + +### `"plan/mode"` + +SHA-256: `f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9` + +`"plan/mode"` + + + +### `"positive"` + +SHA-256: `df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528` + +`"positive"` + + + +### `"product-interaction"` + +SHA-256: `0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23` + +`"product-interaction"` + + + +### `"provider"` + +SHA-256: `e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a` + +`"provider"` + + + +### `"provisioning"` + +SHA-256: `871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62` + +`"provisioning"` + + + +### `"ptc-mode"` + +SHA-256: `4edec1b770e8ec4ce1220bf42edc5ac46713a1b48d4caa778dcfc98bad1f28a3` + +`"ptc-mode"` + + + +### `"read-only"` + +SHA-256: `12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42` + +`"read-only"` + + + +### `"reasoning"` + +SHA-256: `3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c` + +`"reasoning"` + + + +### `"reasoning-chunks"` + +SHA-256: `688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8` + +`"reasoning-chunks"` + + + +### `"reasoning-delta"` + +SHA-256: `6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6` + +`"reasoning-delta"` + + + +### `"recall"` + +SHA-256: `383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f` + +`"recall"` + + + +### `"rejected"` + +SHA-256: `fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018` + +`"rejected"` + + + +### `"relay"` + +SHA-256: `16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e` + +`"relay"` + + + +### `"remove"` + +SHA-256: `7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc` + +`"remove"` + + + +### `"repeat-tool-reminder"` + +SHA-256: `1f1385dbc3e875c021e387c7096d671d606f22daec51b25c80348735b6bbfa10` + +`"repeat-tool-reminder"` + + + +### `"replace"` + +SHA-256: `f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8` + +`"replace"` + + + +### `"request/context"` + +SHA-256: `70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2` + +`"request/context"` + + + +### `"request/header"` + +SHA-256: `3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e` + +`"request/header"` + + + +### `"resource-cost"` + +SHA-256: `5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75` + +`"resource-cost"` + + + +### `"resume"` + +SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66` + +`"resume"` + + + +### `"runtime-context"` + +SHA-256: `24b10f7cdae64928f89c49afc2eca0af9eb4a2f135e16f3416e6b8461fef1748` + +`"runtime-context"` + + + +### `"sandbox/mode"` + +SHA-256: `ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2` + +`"sandbox/mode"` + + + +### `"schedule"` + +SHA-256: `d9edf1862e4471d6ad8a106a3f4160e0643874368707d50ecd8e27e5ee7a2567` + +`"schedule"` + + + +### `"schedule/change"` + +SHA-256: `0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d` + +`"schedule/change"` + + + +### `"security-privacy-permission"` + +SHA-256: `07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7` + +`"security-privacy-permission"` + + + +### `"series"` + +SHA-256: `4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f` + +`"series"` + + + +### `"service-stability"` + +SHA-256: `7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732` + +`"service-stability"` + + + +### `"session"` + +SHA-256: `e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828` + +`"session"` + + + +### `"session-log-deepseek/delivery-accepted"` + +SHA-256: `47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b` + +`"session-log-deepseek/delivery-accepted"` + + + +### `"session-reference"` + +SHA-256: `7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71` + +`"session-reference"` + + + +### `"session/end-seed"` + +SHA-256: `1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330` + +`"session/end-seed"` + + + +### `"session/title"` + +SHA-256: `7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50` + +`"session/title"` + + + +### `"session/title-llm-request"` + +SHA-256: `587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e` + +`"session/title-llm-request"` + + + +### `"set"` + +SHA-256: `b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b` + +`"set"` + + + +### `"skill-catalog"` + +SHA-256: `6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3` + +`"skill-catalog"` + + + +### `"skill-invocation"` + +SHA-256: `1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509` + +`"skill-invocation"` + + + +### `"snapshot"` + +SHA-256: `6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912` + +`"snapshot"` + + + +### `"step/end"` + +SHA-256: `c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70` + +`"step/end"` + + + +### `"step/start"` + +SHA-256: `2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d` + +`"step/start"` + + + +### `"stop"` + +SHA-256: `57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90` + +`"stop"` + + + +### `"subagent"` + +SHA-256: `aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6` + +`"subagent"` + + + +### `"subagent-settled"` + +SHA-256: `bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a` + +`"subagent-settled"` + + + +### `"subagent/catalog"` + +SHA-256: `44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2` + +`"subagent/catalog"` + + + +### `"subagent/descriptor"` + +SHA-256: `5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647` + +`"subagent/descriptor"` + + + +### `"subagent/model-selection-policy"` + +SHA-256: `0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da` + +`"subagent/model-selection-policy"` + + + +### `"success"` + +SHA-256: `511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7` + +`"success"` + + + +### `"system"` + +SHA-256: `8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3` + +`"system"` + + + +### `"system-prompt"` + +SHA-256: `09655b34d7f3cf1e9005974de2357de2d4a60deea165d16dac1eadaa6ec539a8` + +`"system-prompt"` + + + +### `"system/message"` + +SHA-256: `1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7` + +`"system/message"` + + + +### `"task-result"` + +SHA-256: `f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c` + +`"task-result"` + + + +### `"team-message"` + +SHA-256: `2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c` + +`"team-message"` + + + +### `"team/member"` + +SHA-256: `18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0` + +`"team/member"` + + + +### `"team/message/delivered"` + +SHA-256: `a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57` + +`"team/message/delivered"` + + + +### `"team/message/queued"` + +SHA-256: `4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159` + +`"team/message/queued"` + + + +### `"team/task"` + +SHA-256: `b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b` + +`"team/task"` + + + +### `"text"` + +SHA-256: `4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d` + +`"text"` + + + +### `"text-chunks"` + +SHA-256: `f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3` + +`"text-chunks"` + + + +### `"text-delta"` + +SHA-256: `5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563` + +`"text-delta"` + + + +### `"time-context"` + +SHA-256: `8067b0d232c350f189738e60ee3c9939d46ca3b32b45db5525237b077893f649` + +`"time-context"` + + + +### `"tmux-context"` + +SHA-256: `78a9be340090b735a39980e7222ce730c972fbcf1de7c9e0aef2125884b7caee` + +`"tmux-context"` + + + +### `"todo/write"` + +SHA-256: `af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7` + +`"todo/write"` + + + +### `"tool"` + +SHA-256: `a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847` + +`"tool"` + + + +### `"tool-addition"` + +SHA-256: `85f9b505b7bdff1f61845c4cea8f36fd0fde1b62facbe87d8924d1d27e616f3a` + +`"tool-addition"` + + + +### `"tool-call"` + +SHA-256: `1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7` + +`"tool-call"` + + + +### `"tool-call-chunks"` + +SHA-256: `616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5` + +`"tool-call-chunks"` + + + +### `"tool-call-delta"` + +SHA-256: `9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267` + +`"tool-call-delta"` + + + +### `"tool-calls"` + +SHA-256: `6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b` + +`"tool-calls"` + + + +### `"tool-goal"` + +SHA-256: `2f3f201c8846e19c20bb75c02280e3d4eb3c57509e4715f0c0a4d1d4f91a7a06` + +`"tool-goal"` + + + +### `"tool-jobs"` + +SHA-256: `99e7e7d7fed55ae6a3a648b35192f16ab1248ddcb0179a0e275128ac1487d7c7` + +`"tool-jobs"` + + + +### `"tool-registry"` + +SHA-256: `a720757f704a2512e9d2f20da4a093e582472176236a75ab8b8eb7aaff17d85a` + +`"tool-registry"` + + + +### `"tool-removal"` + +SHA-256: `83d6916021eede8f2d83a1872716caa1efdec39a3681890996c55147187fdd12` + +`"tool-removal"` + + + +### `"tool-workflow/agent-end"` + +SHA-256: `5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e` + +`"tool-workflow/agent-end"` + + + +### `"tool-workflow/agent-start"` + +SHA-256: `ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8` + +`"tool-workflow/agent-start"` + + + +### `"tool-workflow/run-end"` + +SHA-256: `fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd` + +`"tool-workflow/run-end"` + + + +### `"tool-workflow/run-start"` + +SHA-256: `cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670` + +`"tool-workflow/run-start"` + + + +### `"tool/call"` + +SHA-256: `c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92` + +`"tool/call"` + + + +### `"tool/ptc-dispatch"` + +SHA-256: `fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973` + +`"tool/ptc-dispatch"` + + + +### `"tool/ptc-dispatch-start"` + +SHA-256: `2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456` + +`"tool/ptc-dispatch-start"` + + + +### `"tool/result"` + +SHA-256: `570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833` + +`"tool/result"` + + + +### `"turn/end"` + +SHA-256: `4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03` + +`"turn/end"` + + + +### `"turn/start"` + +SHA-256: `0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f` + +`"turn/start"` + + + +### `"unavailable"` + +SHA-256: `2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c` + +`"unavailable"` + + + +### `"usage"` + +SHA-256: `0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9` + +`"usage"` + + + +### `"user"` + +SHA-256: `68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573` + +`"user"` + + + +### `"user-approval"` + +SHA-256: `f68c335306535a001127dae6685ece493a0ee7f4e2a851197b6054d8a9ff7394` + +`"user-approval"` + + + +### `"user/message"` + +SHA-256: `de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f` + +`"user/message"` + + + +### `"web/deepseek-search-llm-request"` + +SHA-256: `6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675` + +`"web/deepseek-search-llm-request"` + + + +### `"web_search"` + +SHA-256: `935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682` + +`"web_search"` + + + +### `"web_search_20250305"` + +SHA-256: `0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e` + +`"web_search_20250305"` + + + +### `"webhook"` + +SHA-256: `db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0` + +`"webhook"` + + + +### `"workspace-write"` + +SHA-256: `a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa` + +`"workspace-write"` + + + +### `"workspace/changes"` + +SHA-256: `8e8155594e07812356b67d732196dda894b0f9c91a5969d51612cf490b0a016d` + +`"workspace/changes"` + + + +### `0` + +SHA-256: `93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35` + +`0` + + + +### `1` + +SHA-256: `f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d` + +`1` + + + +### `2` + +SHA-256: `a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80` + +`2` + + + +### `4` + +SHA-256: `af6e173f7be819bcd0a5c8d77918649c10ce761d8a184ff472f2e01ce64eb2e0` + +`4` + + + + + + + +### `AfterScheduleRecord` + +SHA-256: `27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe` + +Sources: [`packages/schedule/schedule/src/types.ts:13`](../packages/schedule/schedule/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:agent-preset/selected.data`](#persistence-type-eventagent-presetselecteddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"agent-preset/selected"` | +| `afterSeconds` | required | `number` | +| `id` | required | `string` | +| `kind` | required | `"after"` | +| `prompt` | required | `string` | +| `scheduledAt` | required | `string` | - + -### `event:agent-preset/selected.data` + -SHA-256: `6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406` + -Sources: [`packages/preset/agent-presets/src/session.ts:28`](../packages/preset/agent-presets/src/session.ts) +### `AgentInstructionChange` + +SHA-256: `83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239` + +Sources: [`packages/context/agent-instructions/src/render.ts:47`](../packages/context/agent-instructions/src/render.ts) | Property | Presence | Type | |---|---|---| -| `agentPreset` | required | `string` | +| `action` | required | [`union (3 variants)`](#persistence-type-sha256-904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd) | +| `digest` | optional | `string` | +| `path` | required | `string` | +| `scope` | required | `string` | - + -### `event:agent/inbox/spliced` - -SHA-256: `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:agent/inbox/spliced.data`](#persistence-type-eventagentinboxspliceddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"agent/inbox/spliced"` | - - - -### `event:agent/inbox/spliced.data` - -SHA-256: `a6a195c1b4a906d953d24ab5864c9f1881d545460e080a51144adfc9cb058cfe` - -Sources: [`packages/core/agent/src/types.ts:87`](../packages/core/agent/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `inserted` | required | [`event:agent/inbox/spliced.data.inserted`](#persistence-type-eventagentinboxspliceddatainserted) | -| `outcome` | optional | `"canceled"` | -| `removedCount` | optional | `number` | -| `start` | required | `number` | -| `target` | required | [`packages/core/agent/src/types.ts#InboxTarget`](#persistence-type-packagescoreagentsrctypestsinboxtarget) | - - - -### `event:agent/inbox/spliced.data.inserted` - -SHA-256: `300341f890f7b9506a1749fff4fa5239d16ea1c63ff6b15851acb03c20f3b48d` - -Array of [`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage). - - - -### `event:agent/inbox/spliced.data.inserted[0].content` - -SHA-256: `bb72d86bc9ef0b3908bfa57ef98ccccae24d67d945c9f6869ca3cb8577889e75` - -Array of [`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock). - - - -### `event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions` - -SHA-256: `0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef` - -Sources: [`packages/attachment/attachment/src/types.ts:28`](../packages/attachment/attachment/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `height` | required | `number` | -| `width` | required | `number` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[0]` - -SHA-256: `ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05` - -Sources: [`packages/core/session/src/types.ts:189`](../packages/core/session/src/types.ts) · [`packages/interaction/commands/src/types.ts:75`](../packages/interaction/commands/src/types.ts) · [`packages/interaction/commands/src/types.ts:79`](../packages/interaction/commands/src/types.ts) · [`packages/llm/llm/src/message.ts:103`](../packages/llm/llm/src/message.ts) · [`packages/session/session-title/src/types.ts:35`](../packages/session/session-title/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"user"` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[1]` - -SHA-256: `0ddab4577db37a3e0d9e3a91761735c8ef6f5629d526ab8ecaeeea19c097c8f8` - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[11]` - -SHA-256: `6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7` - -Sources: [`packages/api/session-controller/src/types.ts:381`](../packages/api/session-controller/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `clientTimeZone` | optional | `string` | -| `kind` | required | `"user"` | -| `rpcId` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[15].references` - -SHA-256: `df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18` - -Array of [`event:agent/inbox/spliced.data.inserted[0].source[15].references[0]`](#persistence-type-eventagentinboxspliceddatainserted0source15references0). - - - -### `event:agent/inbox/spliced.data.inserted[0].source[15].references[0]` - -SHA-256: `4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4` - -Sources: [`packages/context/session-reference/src/types.ts:18`](../packages/context/session-reference/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `capturedFormatVersion` | optional | `number` | -| `capturedThroughSeq` | required | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | -| `compacted` | required | `boolean` | -| `inputIndex` | required | `number` | -| `label` | required | `string` | -| `omittedBytes` | required | `number` | -| `omittedMessages` | required | `number` | -| `originalMessages` | required | `number` | -| `retainedMessages` | required | `number` | -| `sessionId` | required | `string` | -| `truncated` | required | `boolean` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[16].changes` +### `AgentInstructionChange[]` SHA-256: `2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee` -Array of [`packages/context/agent-instructions/src/render.ts#AgentInstructionChange`](#persistence-type-packagescontextagent-instructionssrcrendertsagentinstructionchange). +Array of [`AgentInstructionChange`](#persistence-type-sha256-83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239). - + -### `event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action` + + + + +### `AgentInstructionSource` + +SHA-256: `6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590` + +Sources: [`packages/context/agent-instructions/src/state.ts:37`](../packages/context/agent-instructions/src/state.ts) + +| Property | Presence | Type | +|---|---|---| +| `baseline` | optional | `true` | +| `baselineIdentity` | optional | `string` | +| `changes` | required | [`AgentInstructionChange[]`](#persistence-type-sha256-2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee) | +| `form` | required | `"instructions"` | +| `kind` | required | `"agent-instructions"` | + + + + + + + +### `AgentMessageSource` + +SHA-256: `4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86` + +Sources: [`packages/subagent/subagent/src/continuation-messages.ts:15`](../packages/subagent/subagent/src/continuation-messages.ts) + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"agent-message"` | +| `senderSessionId` | required | `string` | + + + + + + + +### `ApprovalOutcome` + +SHA-256: `930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7` + +Sources: [`packages/interaction/user-approval/src/types.ts:32`](../packages/interaction/user-approval/src/types.ts) + +One of: + +- `"allowed-once"` +- `"cancelled"` +- `"rejected"` +- `"unavailable"` + + + + + + + +### `ApprovalPolicy` + +SHA-256: `05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf` + +Sources: [`packages/interaction/user-approval/src/index.ts:67`](../packages/interaction/user-approval/src/index.ts) + +One of: + +- `"ask"` +- `"never"` + + + + + + + +### `AssistantMessage` + +SHA-256: `fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be` + +Sources: [`packages/llm/llm/src/message.ts:167`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | required | `string` | +| `role` | required | `"assistant"` | +| `source` | required | [`ModelMessageSource`](#persistence-type-sha256-719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91) | + + + + + + + +### `AssistantStreamRecord` + +SHA-256: `33341aac09312300de5a178e6cc6f6544a4876f7f710cfea55eda473c8d329ef` + +Sources: [`packages/llm/llm/src/assistant-stream.ts:20`](../packages/llm/llm/src/assistant-stream.ts) + +One of: + +- [`{ type: "tool-call-chunks" }`](#persistence-type-sha256-3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6) +- [`{ type: "chunk" }`](#persistence-type-sha256-487b65c37bfedb8b72088c4107a0a90a6249701f6b26745f6d98f9b8a22b07c7) +- [`{ type: "reasoning-chunks" }`](#persistence-type-sha256-71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd) +- [`{ type: "text-chunks" }`](#persistence-type-sha256-e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33) + + + +### `AssistantStreamRecord[]` + +SHA-256: `84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7` + +Array of [`AssistantStreamRecord`](#persistence-type-sha256-33341aac09312300de5a178e6cc6f6544a4876f7f710cfea55eda473c8d329ef). + + + + + + + +### `AtScheduleRecord` + +SHA-256: `658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e` + +Sources: [`packages/schedule/schedule/src/types.ts:27`](../packages/schedule/schedule/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `kind` | required | `"at"` | +| `prompt` | required | `string` | +| `scheduledAt` | required | `string` | + + + + + + + +### `CommandSource` + +SHA-256: `ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05` + +Sources: [`packages/core/session/src/types.ts:190`](../packages/core/session/src/types.ts) · [`packages/interaction/commands/src/types.ts:75`](../packages/interaction/commands/src/types.ts) · [`packages/interaction/commands/src/types.ts:79`](../packages/interaction/commands/src/types.ts) · [`packages/llm/llm/src/message.ts:111`](../packages/llm/llm/src/message.ts) · [`packages/session/session-title/src/types.ts:35`](../packages/session/session-title/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"user"` | + + + + + + + +### `CompactionCheckpointSource` + +SHA-256: `31907de9563751822af6d9be02bafaf26faa098bbd1cb412524134d577cc1648` + +Sources: [`packages/compaction/compaction/src/checkpoint.ts:22`](../packages/compaction/compaction/src/checkpoint.ts) + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `kind` | required | `"compact-checkpoint"` | +| `sourceCommandId` | optional | `string` | + + + + + + + +### `ContentBlock` + +SHA-256: `8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5` + +Sources: [`packages/llm/llm/src/types.ts:151`](../packages/llm/llm/src/types.ts) + +One of: + +- [`ReasoningBlock`](#persistence-type-sha256-814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e) +- [`TextBlock`](#persistence-type-sha256-4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c) +- [`ToolAdditionBlock`](#persistence-type-sha256-8e611bf46821e5003a1605a73560a6f56388295149d449dfe2142d5ec335f29c) +- [`ToolRemovalBlock`](#persistence-type-sha256-43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8) +- [`ToolCallBlock`](#persistence-type-sha256-c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea) +- [`ImageBlock`](#persistence-type-sha256-12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7) +- [`FileBlock`](#persistence-type-sha256-f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef) + + + + + + + +### `ContentBlockType` + +SHA-256: `7d65acf0a3a43a8f445ce5d3320b42eca492739fc931b2a7516bfb8368dc2c68` + +Sources: [`packages/llm/llm/src/types.ts:149`](../packages/llm/llm/src/types.ts) + +One of: + +- `"file"` +- `"image"` +- `"reasoning"` +- `"text"` +- `"tool-addition"` +- `"tool-call"` +- `"tool-removal"` + + + +### `ContentBlock[]` + +SHA-256: `b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1` + +Array of [`ContentBlock`](#persistence-type-sha256-8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5). + + + + + + + +### `ContextSnapshotSection` + +SHA-256: `86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219` + +Sources: [`packages/llm/llm/src/message.ts:70`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `name` | required | `string` | +| `text` | required | `string` | + + + +### `ContextSnapshotSection[]` + +SHA-256: `c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262` + +Array of [`ContextSnapshotSection`](#persistence-type-sha256-86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219). + + + + + + + +### `ContinuableSubagentDescriptorData` + +SHA-256: `6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f` + +Sources: [`packages/subagent/subagent/src/descriptor.ts:72`](../packages/subagent/subagent/src/descriptor.ts) + +| Property | Presence | Type | +|---|---|---| +| `agentModel` | optional | `string` | +| `agentProvider` | optional | `string` | +| `agentReasoningEffort` | optional | `string` | +| `label` | required | `string` | +| `mode` | required | `"continuable"` | +| `persona` | optional | `string` | +| `provider` | required | `string` | +| `toolFilter` | optional | [`ToolRestriction`](#persistence-type-sha256-3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f) | +| `version` | required | `number` | + + + + + + + +### `DeepSeekSearchLlmRequest` + +SHA-256: `2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9` + +Sources: [`packages/web/web-search-deepseek/src/provider.ts:55`](../packages/web/web-search-deepseek/src/provider.ts) + +| Property | Presence | Type | +|---|---|---| +| `apiVersion` | required | `string` | +| `body` | required | [`{ max_tokens, messages, model, tools }`](#persistence-type-sha256-930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731) | +| `endpoint` | required | `string` | + + + + + + + +### `DeveloperMessage` + +SHA-256: `f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b` + +Sources: [`packages/llm/llm/src/message.ts:157`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | required | `string` | +| `role` | required | `"developer"` | +| `source` | required | [`MessageSource`](#persistence-type-sha256-40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945) | + +Source compatibility: `source` — `session-source-attribution` v1; `session.developer-message.source`; `kind`; `preserve`. + +Attribution-only additions: `tmux-context`. + + + + + + + +### `EpochHeader` + +SHA-256: `9a930283b91d493d6347146f2475bb107294b379415ca02162354f46a64164f7` + +Sources: [`packages/core/session/src/types.ts:240`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `adapterDefaults` | optional | [`LlmCallConfigAdapterDefaults`](#persistence-type-sha256-326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693) | +| `config` | required | [`LlmCallConfig`](#persistence-type-sha256-67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0) | +| `system` | optional | `never` | +| `tools` | optional | [`ToolSchema[]`](#persistence-type-sha256-a0baff42eb900561f91032b6950a3925cf19c5c8d9ba33948ac69e4ac7dee573) | + + + + + + + +### `EveryScheduleDispatchChange` + +SHA-256: `e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344` + +Sources: [`packages/schedule/schedule/src/types.ts:93`](../packages/schedule/schedule/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `acceptedAt` | required | `string` | +| `id` | required | `string` | +| `operation` | required | `"dispatch"` | +| `version` | required | `1` | + + + + + + + +### `EveryScheduleRecord` + +SHA-256: `66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14` + +Sources: [`packages/schedule/schedule/src/types.ts:39`](../packages/schedule/schedule/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `everySeconds` | required | `number` | +| `id` | required | `string` | +| `kind` | required | `"every"` | +| `prompt` | required | `string` | +| `scheduledAt` | required | `string` | + + + + + + + +### `FeedbackRecord` + +SHA-256: `7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344` + +Sources: [`packages/feedback/command-feedback/src/types.ts:27`](../packages/feedback/command-feedback/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `category` | optional | [`union (7 variants)`](#persistence-type-sha256-3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd) | +| `text` | optional | `string` | + + + + + + + +### `FileAttachmentRef` + +SHA-256: `f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6` + +Sources: [`packages/attachment/attachment/src/types.ts:39`](../packages/attachment/attachment/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `attachmentId` | required | `string` | +| `bytes` | required | `number` | +| `name` | required | `string` | + + + + + + + +### `FileBlock` + +SHA-256: `f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef` + +Sources: [`packages/llm/llm/src/types.ts:98`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `attachment` | required | [`FileAttachmentRef`](#persistence-type-sha256-f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6) | +| `type` | required | `"file"` | + + + + + + + +### `FinishReason` + +SHA-256: `5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80` + +Sources: [`packages/llm/llm/src/types.ts:166`](../packages/llm/llm/src/types.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `aborted` | not declared | `failure`: [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | [`{ failure, kind: "aborted" }`](#persistence-type-sha256-8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0) | +| `error` | not declared | `failure`: [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | [`{ failure, kind: "error" }`](#persistence-type-sha256-693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057) | +| `max-tokens` | not declared | none | [`{ kind: "max-tokens" }`](#persistence-type-sha256-ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7) | +| `stop` | not declared | none | [`{ kind: "stop" }`](#persistence-type-sha256-1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f) | +| `tool-calls` | not declared | none | [`{ kind: "tool-calls" }`](#persistence-type-sha256-287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a) | + + + + + + + +### `GoalBlockReason` + +SHA-256: `84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c` + +Sources: [`packages/goal/goal/src/types.ts:52`](../packages/goal/goal/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `code` | required | `string` | +| `message` | required | `string` | + + + + + + + +### `GoalChangeMeta` + +SHA-256: `7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438` + +Sources: [`packages/goal/goal/src/domain.ts:44`](../packages/goal/goal/src/domain.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `goal/change` | not declared | `createdAt`: `number`; `goal`: [`GoalSnapshot`](#persistence-type-sha256-6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25); `operation`: [`union (6 variants)`](#persistence-type-sha256-62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379); `roundsStarted`: `number`; `updatedAt`: `number`; `version`: `1` | [`GoalSnapshotChangeMeta`](#persistence-type-sha256-1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4) | +| `goal/change` | not declared | `cleared`: [`GoalRef`](#persistence-type-sha256-0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f); `clearedAt`: `number`; `operation`: `"clear"`; `version`: `1` | [`GoalClearChangeMeta`](#persistence-type-sha256-cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f) | + + + + + + + +### `GoalClearChangeMeta` + +SHA-256: `cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f` + +Sources: [`packages/goal/goal/src/domain.ts:35`](../packages/goal/goal/src/domain.ts) + +| Property | Presence | Type | +|---|---|---| +| `cleared` | required | [`GoalRef`](#persistence-type-sha256-0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f) | +| `clearedAt` | required | `number` | +| `kind` | required | `"goal/change"` | +| `operation` | required | `"clear"` | +| `version` | required | `1` | + + + + + + + +### `GoalMessageSource` + +SHA-256: `7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc` + +Sources: [`packages/goal/goal/src/domain.ts:47`](../packages/goal/goal/src/domain.ts) + +| Property | Presence | Type | +|---|---|---| +| `goalId` | required | `string` | +| `kind` | required | `"goal"` | +| `revision` | required | `number` | +| `round` | required | `number` | + + + + + + + +### `GoalPhase` + +SHA-256: `b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172` + +Sources: [`packages/goal/goal/src/types.ts:45`](../packages/goal/goal/src/types.ts) + +One of: + +- `"active"` +- `"blocked"` +- `"complete"` +- `"paused"` + + + + + + + +### `GoalRef` + +SHA-256: `0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f` + +Sources: [`packages/goal/goal/src/types.ts:20`](../packages/goal/goal/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `revision` | required | `number` | + + + + + + + +### `GoalSnapshot` + +SHA-256: `6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25` + +Sources: [`packages/goal/goal/src/types.ts:60`](../packages/goal/goal/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `blockedReason` | optional | [`GoalBlockReason`](#persistence-type-sha256-84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c) | +| `id` | required | `string` | +| `maxGoalRounds` | required | `number` | +| `objective` | required | `string` | +| `phase` | required | [`GoalPhase`](#persistence-type-sha256-b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172) | +| `revision` | required | `number` | + + + + + + + +### `GoalSnapshotChangeMeta` + +SHA-256: `1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4` + +Sources: [`packages/goal/goal/src/domain.ts:24`](../packages/goal/goal/src/domain.ts) + +| Property | Presence | Type | +|---|---|---| +| `createdAt` | required | `number` | +| `goal` | required | [`GoalSnapshot`](#persistence-type-sha256-6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25) | +| `kind` | required | `"goal/change"` | +| `operation` | required | [`union (6 variants)`](#persistence-type-sha256-62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379) | +| `roundsStarted` | required | `number` | +| `updatedAt` | required | `number` | +| `version` | required | `1` | + + + + + + + + + +### `HeaderLine` + +SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` + +Sources: [`packages/session/session-persistence-jsonl/src/format.ts:83`](../packages/session/session-persistence-jsonl/src/format.ts) + +| Property | Presence | Type | +|---|---|---| +| `agentPreset` | optional | `string` | +| `createdAt` | required | `number` | +| `cwd` | optional | `string` | +| `delegationDepth` | required | `number` | +| `id` | required | `string` | +| `isSeeded` | required | `boolean` | +| `origin` | optional | `"subagent"` | +| `parentSession` | optional | `string` | +| `type` | required | `"session"` | +| `version` | required | `number` | + + + + + + + +### `HookDialect` + +SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` + +Sources: [`packages/hooks/hook-protocol/src/types.ts:48`](../packages/hooks/hook-protocol/src/types.ts) + +One of: + +- `"claude-code"` +- `"codex"` + + + + + + + +### `ImageAttachmentRef` + +SHA-256: `b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35` + +Sources: [`packages/attachment/attachment/src/types.ts:11`](../packages/attachment/attachment/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `attachmentId` | required | `string` | +| `bytes` | required | `number` | +| `height` | required | `number` | +| `mediaType` | required | [`ImageMediaType`](#persistence-type-sha256-2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716) | +| `name` | optional | `string` | +| `originalDimensions` | optional | [`{ height, width }`](#persistence-type-sha256-0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef) | +| `width` | required | `number` | + + + + + + + +### `ImageBlock` + +SHA-256: `12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7` + +Sources: [`packages/llm/llm/src/types.ts:79`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `attachment` | required | [`ImageAttachmentRef`](#persistence-type-sha256-b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35) | +| `offloaded` | optional | `true` | +| `type` | required | `"image"` | + + + + + + + +### `ImageMediaType` + +SHA-256: `2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716` + +Sources: [`packages/attachment/attachment/src/types.ts:8`](../packages/attachment/attachment/src/types.ts) + +One of: + +- `"image/gif"` +- `"image/jpeg"` +- `"image/png"` +- `"image/webp"` + + + + + + + +### `ImageOffloadTarget` + +SHA-256: `1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f` + +Sources: [`packages/compaction/compaction-image-offload/src/projection.ts:9`](../packages/compaction/compaction-image-offload/src/projection.ts) + +| Property | Presence | Type | +|---|---|---| +| `imageIndexes` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `seq` | required | `number` | + + + +### `ImageOffloadTarget[]` + +SHA-256: `9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb` + +Array of [`ImageOffloadTarget`](#persistence-type-sha256-1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f). + + + + + + + +### `InboxTarget` + +SHA-256: `96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c` + +Sources: [`packages/core/agent/src/types.ts:30`](../packages/core/agent/src/types.ts) + +One of: + +- `"next-step"` +- `"next-turn"` + + + + + + + +### `JsonValue` + +SHA-256: `c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6` + +Sources: [`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) + +One of: + +- [`JsonValue[]`](#persistence-type-sha256-72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227) +- [`{}`](#persistence-type-sha256-529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05) +- `string` +- `boolean` +- `null` +- `number` + + + +### `JsonValue[]` + +SHA-256: `72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227` + +Array of [`JsonValue`](#persistence-type-sha256-c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6). + + + + + + + +### `LlmCallConfig` + +SHA-256: `67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0` + +Sources: [`packages/llm/llm/src/call-config.ts:23`](../packages/llm/llm/src/call-config.ts) + +| Property | Presence | Type | +|---|---|---| +| `maxTokens` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `reasoningEffort` | optional | `string` | +| `stop` | optional | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `temperature` | optional | `number` | + + + + + + + +### `LlmCallConfigAdapterDefaults` + +SHA-256: `326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693` + +Sources: [`packages/llm/llm/src/call-config.ts:36`](../packages/llm/llm/src/call-config.ts) + +| Property | Presence | Type | +|---|---|---| +| `maxTokens` | optional | `true` | +| `reasoningEffort` | optional | `true` | + + + + + + + +### `LlmFailure` + +SHA-256: `5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca` + +Sources: [`packages/llm/llm/src/types.ts:41`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `code` | required | `string` | +| `message` | required | `string` | +| `offloadImages` | optional | `number` | +| `providerRetryAfterMs` | optional | `number` | +| `requestId` | optional | `string` | +| `status` | optional | `number` | + + + + + + + +### `LlmRetryEventData` + +SHA-256: `c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1` + +Sources: [`packages/llm/llm-retry/src/types.ts:16`](../packages/llm/llm-retry/src/types.ts) + +One of: + +- [`{ delayMs, failure, maxRetries, mode, … }`](#persistence-type-sha256-cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced) +- [`{ delayMs, failure, mode, policyKey, … }`](#persistence-type-sha256-374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b) + + + + + + + +### `LlmRetryStartedEventData` + +SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20` + +Sources: [`packages/llm/llm-retry/src/types.ts:43`](../packages/llm/llm-retry/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `retry` | required | `number` | +| `retryId` | required | `string` | +| `step` | required | `number` | +| `turn` | required | `number` | + + + + + + + +### `Message` + +SHA-256: `691c0f641cd3e8072fdacd6fa8c400253cf75a0ce9285d8ce89141bbb24f2fb6` + +Sources: [`packages/llm/llm/src/message.ts:196`](../packages/llm/llm/src/message.ts) + +One of: + +- [`ToolResultMessage`](#persistence-type-sha256-4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731) +- [`DeveloperMessage`](#persistence-type-sha256-f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b) +- [`UserMessage`](#persistence-type-sha256-64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586) +- [`AssistantMessage`](#persistence-type-sha256-fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be) +- [`SystemMessage`](#persistence-type-sha256-09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363) + + + + + + + +### `MessageFeedbackDelete` + +SHA-256: `7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06` + +Sources: [`packages/feedback/message-feedback/src/types.ts:46`](../packages/feedback/message-feedback/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `messageId` | required | `string` | +| `sessionId` | required | `string` | + + + + + + + +### `MessageFeedbackItem` + +SHA-256: `3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182` + +Sources: [`packages/feedback/message-feedback/src/types.ts:20`](../packages/feedback/message-feedback/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `category` | optional | [`union (7 variants)`](#persistence-type-sha256-3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd) | +| `createdAt` | required | `number` | +| `messageId` | required | `string` | +| `note` | optional | `string` | +| `rating` | required | [`MessageFeedbackRating`](#persistence-type-sha256-390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2) | +| `updatedAt` | required | `number` | +| `version` | required | `string` | + + + + + + + +### `MessageFeedbackPut` + +SHA-256: `aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626` + +Sources: [`packages/feedback/message-feedback/src/types.ts:38`](../packages/feedback/message-feedback/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `item` | required | [`MessageFeedbackItem`](#persistence-type-sha256-3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182) | +| `sessionId` | required | `string` | + + + + + + + +### `MessageFeedbackRating` + +SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2` + +Sources: [`packages/feedback/message-feedback/src/types.ts:17`](../packages/feedback/message-feedback/src/types.ts) + +One of: + +- `"negative"` +- `"positive"` + + + + + + + +### `MessageSource` + +SHA-256: `40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945` + +Sources: [`packages/llm/llm/src/message.ts:136`](../packages/llm/llm/src/message.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `agent-instructions` | `"instructions"` | `changes`: [`AgentInstructionChange[]`](#persistence-type-sha256-2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee) | [`AgentInstructionSource`](#persistence-type-sha256-6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590) | +| `agent-message` | `"relay"` | `senderSessionId`: `string` | [`AgentMessageSource`](#persistence-type-sha256-4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86) | +| `compact-checkpoint` | not declared | `compactionId`: `string` | [`CompactionCheckpointSource`](#persistence-type-sha256-31907de9563751822af6d9be02bafaf26faa098bbd1cb412524134d577cc1648) | +| `cordis-host-runner` | not declared | none | [`{ kind: "cordis-host-runner" }`](#persistence-type-sha256-02b2c23f2d94b028c9588a8faace3fce1217405db346da3389368b495457bf79) | +| `dsh-session-title-llm` | `"catalog"` | none | [`{ kind: "dsh-session-title-llm", form: "catalog" }`](#persistence-type-sha256-80677c8c8b804189a0fde8aa70dd4ad7af8bb12dfd03027e8e023c8592c838bc) | +| `dsh-session-title-llm` | `"instructions"` | none | [`{ kind: "dsh-session-title-llm", form: "instructions" }`](#persistence-type-sha256-224aa11d4d5f88c450822d01b99e6ca5e3a9c7f26a5ede10bae33384a09ef4dc) | +| `dsh-session-title-llm` | `"notice"` | `summary`: `string` | [`{ kind: "dsh-session-title-llm", form: "notice" }`](#persistence-type-sha256-8338ee303e2bd448e9e6144069942f63e3cfd5868962bddc9347d7009e8919d6) | +| `dsh-session-title-llm` | `"recall"` | none | [`{ kind: "dsh-session-title-llm", form: "recall" }`](#persistence-type-sha256-b2a5c8c008a31e3dc6c3013502f2356aca13894b31c8e70601fa92f2d40d1dba) | +| `dsh-session-title-llm` | `"relay"` | none | [`{ kind: "dsh-session-title-llm", form: "relay" }`](#persistence-type-sha256-7eaef7a763ba5b949b8464bc8add8980a3a5ab566014b69787aeba71e5dfe07b) | +| `dsh-session-title-llm` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "dsh-session-title-llm", form: "snapshot" }`](#persistence-type-sha256-ba4c40b4381e0dcdfab8fc9fc75b5c9b3e8f09ef56deeb1bec8e703b0ef8cd6d) | +| `dsh-session-title-llm` | not declared | none | [`{ kind: "dsh-session-title-llm" }`](#persistence-type-sha256-290f32bfd81ff85a8095886a8066fae06e885942b63a8bcd6a8d66d328445808) | +| `goal` | not declared | `goalId`: `string`; `revision`: `number`; `round`: `number` | [`GoalMessageSource`](#persistence-type-sha256-7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc) | +| `hooks-claude-code` | `"catalog"` | none | [`{ kind: "hooks-claude-code", form: "catalog" }`](#persistence-type-sha256-297fbd8067d7815adae02b89790ec6ff5fb7c2cb0d0eb026e1746c24ec857761) | +| `hooks-claude-code` | `"instructions"` | none | [`{ kind: "hooks-claude-code", form: "instructions" }`](#persistence-type-sha256-b70f3e81fe11b7a5f2504fb47a4502fb8d9c8f0731fdfe8ddcaf9b41f5a6e196) | +| `hooks-claude-code` | `"notice"` | `summary`: `string` | [`{ kind: "hooks-claude-code", form: "notice" }`](#persistence-type-sha256-edbbfff1128099fda7b792c56330d2cb04debc9790988e66d1c3f4026e813e0e) | +| `hooks-claude-code` | `"recall"` | none | [`{ kind: "hooks-claude-code", form: "recall" }`](#persistence-type-sha256-87b1a33564b9a4d63b00988a524c12259243953aebb9c9a05127d87b27464df9) | +| `hooks-claude-code` | `"relay"` | none | [`{ kind: "hooks-claude-code", form: "relay" }`](#persistence-type-sha256-6ea608bdc8a7a63d3d23b84c49721325094db88d136482e43a820945295eee3e) | +| `hooks-claude-code` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "hooks-claude-code", form: "snapshot" }`](#persistence-type-sha256-3bdb8dc6989655b0d4ec361edafb8e2629bc263e1ea591819414fdafc1a413b3) | +| `hooks-claude-code` | not declared | none | [`{ kind: "hooks-claude-code" }`](#persistence-type-sha256-0ed8d1108fe7a5e1c3078ef1faea12199a56b6b1216ccaceb0f6103b0c9a7691) | +| `hooks-codex` | `"catalog"` | none | [`{ kind: "hooks-codex", form: "catalog" }`](#persistence-type-sha256-99f0e98184709ad10f27bfdeaafb4457d9d2b413f402331764798cdb7d3cbe4d) | +| `hooks-codex` | `"instructions"` | none | [`{ kind: "hooks-codex", form: "instructions" }`](#persistence-type-sha256-b6f94c17dd9bbd7cd57015198b7c7c88407f0e3b89faab176ca3c11c3d864d3e) | +| `hooks-codex` | `"notice"` | `summary`: `string` | [`{ kind: "hooks-codex", form: "notice" }`](#persistence-type-sha256-854db3efdfb0cd39d30953b28703e519c121f1115cebfffc40369fe86c406dd1) | +| `hooks-codex` | `"recall"` | none | [`{ kind: "hooks-codex", form: "recall" }`](#persistence-type-sha256-3b4f2c9ef2c1217eac596c7b070173cb7896e2fae09e729bc7c56c801e56bb29) | +| `hooks-codex` | `"relay"` | none | [`{ kind: "hooks-codex", form: "relay" }`](#persistence-type-sha256-1fdad624334d354820dfb3a26e28d0bc9fc1b62a33f87bab63f715b3f4391bfd) | +| `hooks-codex` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "hooks-codex", form: "snapshot" }`](#persistence-type-sha256-88841202942c7683b3b7e5ea6a796047ec326b6701ac23e58cc236d85613b9fa) | +| `hooks-codex` | not declared | none | [`{ kind: "hooks-codex" }`](#persistence-type-sha256-b4ec0af39fd52ed971990e42f04e5be3204882e555c409eb330f8238eec21569) | +| `model` | not declared | `model`: `string`; `provider`: `string` | [`ModelMessageSource`](#persistence-type-sha256-719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91) | +| `model-selection` | `"catalog"` | none | [`{ kind: "model-selection", form: "catalog" }`](#persistence-type-sha256-99135d8a3937977955eaac5f8f04f930dcd1562f8450a54a51cde9b921dd59a6) | +| `model-selection` | `"instructions"` | none | [`{ kind: "model-selection", form: "instructions" }`](#persistence-type-sha256-f6605d6c57933aeaaf10911b5fbd6c61e655baa181af7192d3240f49d255b90d) | +| `model-selection` | `"notice"` | `summary`: `string` | [`{ kind: "model-selection", form: "notice" }`](#persistence-type-sha256-a3c6f1ea38e9a61d7a9706057ba65aabe02dfe6d9dd90d4736aa62325d874531) | +| `model-selection` | `"recall"` | none | [`{ kind: "model-selection", form: "recall" }`](#persistence-type-sha256-aae343bc3d663c83f2e8b5e1c7eea5d509dc7a5361bc8bd8b5ac3bb8d3b1ed56) | +| `model-selection` | `"relay"` | none | [`{ kind: "model-selection", form: "relay" }`](#persistence-type-sha256-a15a19ef63cf5d1b711db1d249821dab0cedcd3a9ad09137b47352c93841fd20) | +| `model-selection` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "model-selection", form: "snapshot" }`](#persistence-type-sha256-52c6113cb0e53f345324bf84f01928bea5d5df57ee80bc0dd65407b8bc5a3734) | +| `model-selection` | not declared | none | [`{ kind: "model-selection" }`](#persistence-type-sha256-f7283223aacdc39b0adca728c8cbd4c090a20006a6fecec74421c30e943b489c) | +| `plan-mode` | `"catalog"` | none | [`{ kind: "plan-mode", form: "catalog" }`](#persistence-type-sha256-3b04790e08b35241ffa0d38f6d7e4f8788aa921341f6c0d7574a329397c59408) | +| `plan-mode` | `"instructions"` | none | [`{ kind: "plan-mode", form: "instructions" }`](#persistence-type-sha256-408927267422a7b2beb6df354ff7c1406d929a5646554f48adf85eb8372f811c) | +| `plan-mode` | `"notice"` | `summary`: `string` | [`{ kind: "plan-mode", form: "notice" }`](#persistence-type-sha256-baccc97ec34be6c4c78e95aa88c85c29820269479445e5b13f956cd64c5e286f) | +| `plan-mode` | `"recall"` | none | [`{ kind: "plan-mode", form: "recall" }`](#persistence-type-sha256-f6329fb30c7ea8013e8975ca5e78284fb7685cc6bd620e8aa4e9a99bc81d45eb) | +| `plan-mode` | `"relay"` | none | [`{ kind: "plan-mode", form: "relay" }`](#persistence-type-sha256-deaae5cd30987d4f49398e8f9d994c125907e7f928300745fb1dbf15f145d0e7) | +| `plan-mode` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "plan-mode", form: "snapshot" }`](#persistence-type-sha256-8c1c4f72755a78ea163523a46565316e36e9b644382eb48e6635c71a6f412dd2) | +| `plan-mode` | not declared | none | [`{ kind: "plan-mode" }`](#persistence-type-sha256-f4a66f654996c093aae700ea4c434ff2ee3569fea9c0e5813ccf6afdccabd163) | +| `ptc-mode` | not declared | none | [`{ kind: "ptc-mode" }`](#persistence-type-sha256-dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd) | +| `repeat-tool-reminder` | `"catalog"` | none | [`{ kind: "repeat-tool-reminder", form: "catalog" }`](#persistence-type-sha256-d85590a5675c6e2fd8164e5792a6cceac714605b8ac228adae5ee668facb1490) | +| `repeat-tool-reminder` | `"instructions"` | none | [`{ kind: "repeat-tool-reminder", form: "instructions" }`](#persistence-type-sha256-6f44f32be9bcd9a8bf075c3b575b06c8ed63446386e5b0995c7b73762e68ddae) | +| `repeat-tool-reminder` | `"notice"` | `summary`: `string` | [`{ kind: "repeat-tool-reminder", form: "notice" }`](#persistence-type-sha256-fe1a7acdeed4d0f5ab483396eaa5b3dc97263b7c10eb4da2f0028cb01728bfc9) | +| `repeat-tool-reminder` | `"recall"` | none | [`{ kind: "repeat-tool-reminder", form: "recall" }`](#persistence-type-sha256-8620189c8e33582708ece48fd2d20dc4d57912486a17bdbb9aea4c44f7018062) | +| `repeat-tool-reminder` | `"relay"` | none | [`{ kind: "repeat-tool-reminder", form: "relay" }`](#persistence-type-sha256-4991dfc415c9efebc36fa6969e1798c7d2e42396cc1e6e0ac7d7c89c5c5c4aea) | +| `repeat-tool-reminder` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "repeat-tool-reminder", form: "snapshot" }`](#persistence-type-sha256-db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c) | +| `repeat-tool-reminder` | not declared | none | [`{ kind: "repeat-tool-reminder" }`](#persistence-type-sha256-b062078e899958f99ae464514578b8c093924dfe34bd9a835932b420ff2150b1) | +| `runtime-context` | `"catalog"` | none | [`{ kind: "runtime-context", form: "catalog" }`](#persistence-type-sha256-58015da1c1950a66daf66ae24913d6a1fc6d1d9ac441b155f8847f7f8584ba8e) | +| `runtime-context` | `"instructions"` | none | [`{ kind: "runtime-context", form: "instructions" }`](#persistence-type-sha256-0eeb17e1df89b1ebc2902116fe7145e0d321ef0db26e6bdebc802cb8513a01c1) | +| `runtime-context` | `"notice"` | `summary`: `string` | [`{ kind: "runtime-context", form: "notice" }`](#persistence-type-sha256-cda2345a9be9d139df49ccbd16dcba716f3440178bf20ff8b801fda1f5eb77dc) | +| `runtime-context` | `"recall"` | none | [`{ kind: "runtime-context", form: "recall" }`](#persistence-type-sha256-96bfb916a727cd4445a594df264c523fc039749a31bfed924b8cc7bb308a5bb0) | +| `runtime-context` | `"relay"` | none | [`{ kind: "runtime-context", form: "relay" }`](#persistence-type-sha256-cb1c8959e1726f82f9a3d2ef2bc90bf8c451a98fd56175e956022124c770c818) | +| `runtime-context` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "runtime-context", form: "snapshot" }`](#persistence-type-sha256-2aad1179f957631477b582e57cd8f538cb82618fc3fb816bde1171154235b065) | +| `runtime-context` | not declared | none | [`{ kind: "runtime-context" }`](#persistence-type-sha256-0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789) | +| `schedule` | `"catalog"` | none | [`{ kind: "schedule", form: "catalog" }`](#persistence-type-sha256-1e709346005826eb81809eeb76a3f713cf13ad6c5cec75146d07020ab9adc938) | +| `schedule` | `"instructions"` | none | [`{ kind: "schedule", form: "instructions" }`](#persistence-type-sha256-1938c8c20f1cba7c82dbedcfa4f14c3ee191cd77ed3314ee1fc676d44cadf3be) | +| `schedule` | `"notice"` | `summary`: `string` | [`{ kind: "schedule", form: "notice" }`](#persistence-type-sha256-312aee2f0c42aabbae6cc60d92d596d8453c0aeb061c5868d1755a69ef49e69a) | +| `schedule` | `"recall"` | none | [`{ kind: "schedule", form: "recall" }`](#persistence-type-sha256-a16e567c8cd2c55cf1e911aed3c200c4e1f6febb1459ff2a9e7adf159afb68cb) | +| `schedule` | `"relay"` | none | [`{ kind: "schedule", form: "relay" }`](#persistence-type-sha256-5bc66269cfaf614c0ecda8ecb469f23101a7609793fc2b693ac23c4aecdb575e) | +| `schedule` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "schedule", form: "snapshot" }`](#persistence-type-sha256-28936c614bd4e7e2774806edcbb3cbfd3ee643ac1cbf0bbdff43d915505a8fe3) | +| `schedule` | not declared | none | [`{ kind: "schedule" }`](#persistence-type-sha256-f29d63336e8266d80dd7baeab219436db86341304f6be1cd0edb36f5134c4a47) | +| `session-reference` | `"recall"` | `references`: [`{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }[]`](#persistence-type-sha256-df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18); `version`: `1` | [`SessionReferenceSource`](#persistence-type-sha256-f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f) | +| `skill-catalog` | `"catalog"` | `entries`: [`{ description, name }[]`](#persistence-type-sha256-aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba) | [`SkillCatalogSource`](#persistence-type-sha256-fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093) | +| `skill-invocation` | `"instructions"` | `name`: `string` | [`SkillInvocationSource`](#persistence-type-sha256-672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db) | +| `subagent-settled` | `"notice"` | `senderSessionId`: `string`; `summary`: `string` | [`SubagentSettledMessageSource`](#persistence-type-sha256-4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a) | +| `system-prompt` | not declared | none | [`SystemPromptMessageSource`](#persistence-type-sha256-65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad) | +| `team-message` | not declared | `messageId`: `string`; `senderId`: `string`; `senderName`: `string`; `teamId`: `string` | [`TeamMessageSource`](#persistence-type-sha256-2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0) | +| `time-context` | `"catalog"` | none | [`{ kind: "time-context", form: "catalog" }`](#persistence-type-sha256-85fe96bf15d5c7559eec3bae4d6cf1a76fda9f5be05a29c2830cff560cab0c0d) | +| `time-context` | `"instructions"` | none | [`{ kind: "time-context", form: "instructions" }`](#persistence-type-sha256-f6afe41e3926f422fe849debe90819fddd739f0f59e20be9c71018b9554a7f09) | +| `time-context` | `"notice"` | `summary`: `string` | [`{ kind: "time-context", form: "notice" }`](#persistence-type-sha256-ee577a0cc18664c9daee50e9455153321155604f8f1817362f8f4a4b6fb9e1ad) | +| `time-context` | `"recall"` | none | [`{ kind: "time-context", form: "recall" }`](#persistence-type-sha256-756b5e23a5cb2c7f486f366a828f7461c88902af21125bd6810881f4ccbff6cc) | +| `time-context` | `"relay"` | none | [`{ kind: "time-context", form: "relay" }`](#persistence-type-sha256-5d7a64ed6aac5551ebf998dc25e1e7b48a144769913f89702840180e61dc3995) | +| `time-context` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "time-context", form: "snapshot" }`](#persistence-type-sha256-f230c0b583e23b25ee0a61dbe4c05e95c1e2ae44b27939501eb9e03696f0c278) | +| `time-context` | not declared | none | [`{ kind: "time-context" }`](#persistence-type-sha256-b79641a9d25e756636dc0c706fdf3c4583ccb7d4920e009e6e86c0759cf4de4c) | +| `tmux-context` | `"catalog"` | none | [`{ kind: "tmux-context", form: "catalog" }`](#persistence-type-sha256-7df62978a2b7de8540e714152297743e0a622209a46a5ac9513fc0fad73ca23b) | +| `tmux-context` | `"instructions"` | none | [`{ kind: "tmux-context", form: "instructions" }`](#persistence-type-sha256-9f65c43e340bba31cdc0fc37bd93ccb68d5e9b36f47a68c207e95a8e68620a5d) | +| `tmux-context` | `"notice"` | `summary`: `string` | [`{ kind: "tmux-context", form: "notice" }`](#persistence-type-sha256-b3681c026a0b98e98b103f057dfd217fbe904129c090efd668253ec9aea7fece) | +| `tmux-context` | `"recall"` | none | [`{ kind: "tmux-context", form: "recall" }`](#persistence-type-sha256-fcf81d3c58c13593bf2594e342e31734f4ab2d24938dc610875194c6079749c7) | +| `tmux-context` | `"relay"` | none | [`{ kind: "tmux-context", form: "relay" }`](#persistence-type-sha256-f97f47b0eb87905ed77cc27c5e4ed75ef805cb372c98905253709de1aab9b63c) | +| `tmux-context` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "tmux-context", form: "snapshot" }`](#persistence-type-sha256-49dab019d00e8c26f27ad2ccff7b604d69e323ae4d17e0d2a7b6b8a830b1ade2) | +| `tmux-context` | not declared | none | [`{ kind: "tmux-context" }`](#persistence-type-sha256-8a046b52331959aa3394680d6acbe09b8a5447c6b61375f263445bfcef19b7f1) | +| `tool` | not declared | `callId`: `string` | [`ToolMessageSource`](#persistence-type-sha256-d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab) | +| `tool-goal` | `"catalog"` | none | [`{ kind: "tool-goal", form: "catalog" }`](#persistence-type-sha256-260523b412c19ad8c2bb00093b07f64245ff8ba6b2f76c5b545303772ac9704c) | +| `tool-goal` | `"instructions"` | none | [`{ kind: "tool-goal", form: "instructions" }`](#persistence-type-sha256-6085488d223aeffdef51d7ae17655fc26ab22ee13cbed82a50e62e2b6fb5b918) | +| `tool-goal` | `"notice"` | `summary`: `string` | [`{ kind: "tool-goal", form: "notice" }`](#persistence-type-sha256-8c627d7a45fa406cea879a3922105e27ed4c3c7966e264afaf11ea7a330f2dd1) | +| `tool-goal` | `"recall"` | none | [`{ kind: "tool-goal", form: "recall" }`](#persistence-type-sha256-7554565be416b0342053ee6a46256c9dab07c487349b4a5f10bab1edc151c619) | +| `tool-goal` | `"relay"` | none | [`{ kind: "tool-goal", form: "relay" }`](#persistence-type-sha256-8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4) | +| `tool-goal` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "tool-goal", form: "snapshot" }`](#persistence-type-sha256-11638dc58a31496fb6706ced3e23e3a2db1f3b2a8845968c810827a72b5fc811) | +| `tool-goal` | not declared | none | [`{ kind: "tool-goal" }`](#persistence-type-sha256-a2066bd52f61218ba15b758def2641cc6a8bd3d4a594a488ee4c65be356d7e39) | +| `tool-jobs` | `"catalog"` | none | [`{ kind: "tool-jobs", form: "catalog" }`](#persistence-type-sha256-dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5) | +| `tool-jobs` | `"instructions"` | none | [`{ kind: "tool-jobs", form: "instructions" }`](#persistence-type-sha256-53cf1704ae0709c7678bcf070c83c619fc48ca1b5c173b74cfa8702f22a8e492) | +| `tool-jobs` | `"notice"` | `summary`: `string` | [`{ kind: "tool-jobs", form: "notice" }`](#persistence-type-sha256-5bb69b88517f6214f2af4d1a6d2b771e271ad3ad695cc9c2c272069ae698c9bc) | +| `tool-jobs` | `"recall"` | none | [`{ kind: "tool-jobs", form: "recall" }`](#persistence-type-sha256-dd6cc2bb2a8f28248347021ad93565360b196a042360b4cd16b569d3a2a91f2d) | +| `tool-jobs` | `"relay"` | none | [`{ kind: "tool-jobs", form: "relay" }`](#persistence-type-sha256-ade057f4fdc387aec6426f48704a1f9359cfc6fee13f27735b07f9b215ec16ca) | +| `tool-jobs` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "tool-jobs", form: "snapshot" }`](#persistence-type-sha256-c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49) | +| `tool-jobs` | not declared | none | [`{ kind: "tool-jobs" }`](#persistence-type-sha256-24ce31aa528272e59f21cd26da9eca08968bcc97529756a749bfdab71746d9c8) | +| `tool-registry` | not declared | none | [`{ kind: "tool-registry" }`](#persistence-type-sha256-8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543) | +| `user` | not declared | `rpcId`: `string` | [`{ kind: "user" }`](#persistence-type-sha256-6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7) | +| `user` | not declared | none | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | +| `user-approval` | `"catalog"` | none | [`{ kind: "user-approval", form: "catalog" }`](#persistence-type-sha256-825ca23416b1ea9d81442afead5cf9229a6fa05842f042135cc3aa9710a6a2d8) | +| `user-approval` | `"instructions"` | none | [`{ kind: "user-approval", form: "instructions" }`](#persistence-type-sha256-aa2bf9e82b9fdeb94a42af20031fffa30e4e23f01f4ac39757427d4c64c407f0) | +| `user-approval` | `"notice"` | `summary`: `string` | [`{ kind: "user-approval", form: "notice" }`](#persistence-type-sha256-6ccb6bc423fb3952458abf9c1b1c3284208b7e660344b612cc55da773d61afe4) | +| `user-approval` | `"recall"` | none | [`{ kind: "user-approval", form: "recall" }`](#persistence-type-sha256-022623b9ef98ec47ec3c3bae0c51027c70d2601141c5e92e26a0d83d1b4cef06) | +| `user-approval` | `"relay"` | none | [`{ kind: "user-approval", form: "relay" }`](#persistence-type-sha256-5cdbf342b7748d152bc987b68f58e565e5bba4b227e076e2d2120d87662e45cd) | +| `user-approval` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "user-approval", form: "snapshot" }`](#persistence-type-sha256-5654685d7557ec747e74887237065e626a5bdfa426ca43f7fbb0b6fee9b0916c) | +| `user-approval` | not declared | none | [`{ kind: "user-approval" }`](#persistence-type-sha256-6292bcbedaa97feaec5b48a03bb8144b581b93309d9d6c905f26da7a6a7a0a4f) | +| `webhook` | `"notice"` | `deliveryId`: `string`; `provider`: `string`; `ruleId`: `string`; `source`: `string`; `summary`: `string` | [`{ kind: "webhook", form: "notice" }`](#persistence-type-sha256-9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94) | + + + +### `Message[]` + +SHA-256: `fc8242857caf7450d7f68a1f509dce83e237bd21571666006895124cb2246a83` + +Array of [`Message`](#persistence-type-sha256-691c0f641cd3e8072fdacd6fa8c400253cf75a0ce9285d8ce89141bbb24f2fb6). + + + + + + + +### `ModelMessageSource` + +SHA-256: `719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91` + +Sources: [`packages/llm/llm/src/message.ts:24`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"model"` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `replayState` | optional | `unknown` (opaque) | + + + + + + + +### `ModelSelection` + +SHA-256: `f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b` + +Sources: [`packages/api/session-controller/src/types.ts:86`](../packages/api/session-controller/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `model` | required | `string` | +| `provider` | required | `string` | +| `reasoningEffort` | optional | `string` | + + + + + + + +### `OneShotScheduleDispatchChange` + +SHA-256: `8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af` + +Sources: [`packages/schedule/schedule/src/types.ts:86`](../packages/schedule/schedule/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `operation` | required | `"dispatch"` | +| `version` | required | `1` | + + + + + + + +### `OneShotSubagentDescriptorData` + +SHA-256: `5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564` + +Sources: [`packages/subagent/subagent/src/descriptor.ts:61`](../packages/subagent/subagent/src/descriptor.ts) + +| Property | Presence | Type | +|---|---|---| +| `label` | optional | `string` | +| `mode` | required | `"one-shot"` | +| `provider` | required | `string` | +| `version` | required | `number` | + + + + + + + +### `OptionalSessionSeq` + +SHA-256: `3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f` + +Sources: [`packages/core/session/src/types.ts:65`](../packages/core/session/src/types.ts) + +One of: + +- `null` +- `number` + + + + + + + +### `PresentedFile` + +SHA-256: `b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97` + +Sources: [`packages/deliverables/tool-present/src/types.ts:5`](../packages/deliverables/tool-present/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `description` | optional | `string` | +| `path` | required | `string` | + + + +### `PresentedFile[]` + +SHA-256: `1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345` + +Array of [`PresentedFile`](#persistence-type-sha256-b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97). + + + + + + + +### `PtcDispatchEventData` + +SHA-256: `0ee52de154f8955c7abc82cffebc57452dcc8c44dccbdb6ad16c71a11305ead8` + +Sources: [`packages/core/tools/src/types.ts:20`](../packages/core/tools/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `unknown` (opaque) | +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `error` | optional | [`{ code, name, reason? }`](#persistence-type-sha256-a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735) | +| `isError` | required | `boolean` | +| `name` | required | `string` | +| `parentCallId` | required | `string` | +| `rootCallId` | required | `string` | +| `subCallId` | required | `string` | + + + + + + + +### `PtcDispatchStartEventData` + +SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f` + +Sources: [`packages/core/tools/src/types.ts:11`](../packages/core/tools/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `unknown` (opaque) | +| `name` | required | `string` | +| `parentCallId` | required | `string` | +| `rootCallId` | required | `string` | +| `subCallId` | required | `string` | + + + + + + + +### `ReasoningBlock` + +SHA-256: `814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e` + +Sources: [`packages/llm/llm/src/types.ts:68`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `text` | required | `string` | +| `type` | required | `"reasoning"` | + + + + + + + +### `ReplayEnvelope` + +SHA-256: `0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555` + +Sources: [`packages/llm/llm/src/types.ts:418`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `blocks` | optional | [`unknown[]`](#persistence-type-sha256-b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7) | +| `response` | required | `unknown` (opaque) | + + + + + + + +### `RequestContext` + +SHA-256: `b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081` + +Sources: [`packages/core/session/src/types.ts:254`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `contextWindow` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `systemPromptUpdate` | optional | `"in-history"` | + + + + + + + +### `RequestHeaderReason` + +SHA-256: `530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6` + +Sources: [`packages/core/session/src/types.ts:273`](../packages/core/session/src/types.ts) + +One of: + +- `"change"` +- `"initial"` +- `"resume"` +- `"series"` + + + + + + + +### `SandboxMode` + +SHA-256: `fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd` + +Sources: [`packages/sandbox/sandbox/src/index.ts:29`](../packages/sandbox/sandbox/src/index.ts) + +One of: + +- `"danger-full-access"` +- `"read-only"` +- `"workspace-write"` + + + + + + + +### `ScheduleChange` + +SHA-256: `e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1` + +Sources: [`packages/schedule/schedule/src/types.ts:105`](../packages/schedule/schedule/src/types.ts) + +One of: + +- [`EveryScheduleDispatchChange`](#persistence-type-sha256-e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344) +- [`ScheduleDeleteChange`](#persistence-type-sha256-18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0) +- [`OneShotScheduleDispatchChange`](#persistence-type-sha256-8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af) +- [`ScheduleCreateChange`](#persistence-type-sha256-ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f) + + + + + + + +### `ScheduleCreateChange` + +SHA-256: `ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f` + +Sources: [`packages/schedule/schedule/src/types.ts:72`](../packages/schedule/schedule/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `operation` | required | `"create"` | +| `schedule` | required | [`ScheduleRecord`](#persistence-type-sha256-d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87) | +| `version` | required | `1` | + + + + + + + +### `ScheduleDeleteChange` + +SHA-256: `18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0` + +Sources: [`packages/schedule/schedule/src/types.ts:79`](../packages/schedule/schedule/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `operation` | required | `"delete"` | +| `version` | required | `1` | + + + + + + + +### `ScheduleRecord` + +SHA-256: `d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87` + +Sources: [`packages/schedule/schedule/src/types.ts:69`](../packages/schedule/schedule/src/types.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `after` | not declared | `afterSeconds`: `number`; `id`: `string`; `prompt`: `string`; `scheduledAt`: `string` | [`AfterScheduleRecord`](#persistence-type-sha256-27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe) | +| `at` | not declared | `id`: `string`; `prompt`: `string`; `scheduledAt`: `string` | [`AtScheduleRecord`](#persistence-type-sha256-658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e) | +| `every` | not declared | `everySeconds`: `number`; `id`: `string`; `prompt`: `string`; `scheduledAt`: `string` | [`EveryScheduleRecord`](#persistence-type-sha256-66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14) | + + + + + + + +### `SessionHeader` + +SHA-256: `1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445` + +Sources: [`packages/core/session/src/types.ts:94`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `agentPreset` | optional | `string` | +| `createdAt` | required | `number` | +| `cwd` | optional | `string` | +| `delegationDepth` | optional | `number` | +| `id` | required | `string` | +| `isSeeded` | required | `boolean` | +| `origin` | optional | `"subagent"` | +| `parentSession` | optional | `string` | +| `version` | required | `4` | + + + + + + + +### `SessionReferenceSource` + +SHA-256: `f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f` + +Sources: [`packages/context/session-reference/src/types.ts:13`](../packages/context/session-reference/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"session-reference"` | +| `references` | required | [`{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }[]`](#persistence-type-sha256-df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18) | +| `version` | required | `1` | + + + + + + + +### `SessionTitleEventData` + +SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4` + +Sources: [`packages/session/session-title/src/types.ts:41`](../packages/session/session-title/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `messageSeqs` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `source` | required | [`SessionTitleSource`](#persistence-type-sha256-30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f) | +| `title` | required | `string` | + + + + + + + +### `SessionTitleLlmRequestEventData` + +SHA-256: `9bc85364d1f37d9c837db6a3bdd3d1d007d923cdc7401a3322be9f12fdc225fd` + +Sources: [`packages/session/session-title-llm/src/index.ts:34`](../packages/session/session-title-llm/src/index.ts) + +| Property | Presence | Type | +|---|---|---| +| `maxTokens` | required | `number` | +| `messageSeqs` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `messages` | required | [`Message[]`](#persistence-type-sha256-fc8242857caf7450d7f68a1f509dce83e237bd21571666006895124cb2246a83) | +| `route` | required | [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) | +| `system` | required | `string` | +| `titleProvider` | required | `string` | + + + + + + + + + + + +### `SessionTitleModelIdentity` + +SHA-256: `07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235` + +Sources: [`packages/session/session-title/src/types.ts:20`](../packages/session/session-title/src/types.ts) · [`packages/subagent/tool-subagent/src/model-selection.ts:9`](../packages/subagent/tool-subagent/src/model-selection.ts) + +| Property | Presence | Type | +|---|---|---| +| `model` | required | `string` | +| `provider` | required | `string` | + + + +### `SessionTitleModelIdentity[]` + +SHA-256: `ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec` + +Array of [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235). + + + + + + + +### `SessionTitleSource` + +SHA-256: `30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f` + +Sources: [`packages/session/session-title/src/types.ts:28`](../packages/session/session-title/src/types.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `fallback` | not declared | none | [`{ kind: "fallback" }`](#persistence-type-sha256-1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597) | +| `provider` | not declared | `provider`: `string` | [`{ kind: "provider" }`](#persistence-type-sha256-b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812) | +| `user` | not declared | none | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | + + + + + + + +### `SkillCatalogSource` + +SHA-256: `fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093` + +Sources: [`packages/skill/tool-skill/src/index.ts:34`](../packages/skill/tool-skill/src/index.ts) + +| Property | Presence | Type | +|---|---|---| +| `entries` | required | [`{ description, name }[]`](#persistence-type-sha256-aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba) | +| `form` | required | `"catalog"` | +| `kind` | required | `"skill-catalog"` | +| `update` | optional | `true` | + + + + + + + +### `SkillInvocationSource` + +SHA-256: `672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db` + +Sources: [`packages/skill/skill/src/index.ts:146`](../packages/skill/skill/src/index.ts) + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"skill-invocation"` | +| `name` | required | `string` | + + + + + + + +### `StreamChunk` + +SHA-256: `47e9095591ae36e7c39ee62553097772f2bfa16304536a72dbbc3f691f605180` + +Sources: [`packages/llm/llm/src/types.ts:440`](../packages/llm/llm/src/types.ts) + +One of: + +- [`{ type: "tool-call-delta" }`](#persistence-type-sha256-88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a) +- [`{ type: "block-end" }`](#persistence-type-sha256-d4b739491689cc6bb13d07ffac1a32239875abda364c0d5edd8f74faf5e9c00d) +- [`{ type: "block-start" }`](#persistence-type-sha256-3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90) +- [`{ type: "reasoning-delta" }`](#persistence-type-sha256-2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095) +- [`{ type: "text-delta" }`](#persistence-type-sha256-95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65) +- [`{ type: "finish" }`](#persistence-type-sha256-a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1) +- [`{ type: "usage" }`](#persistence-type-sha256-f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515) + + + + + + + +### `SubagentCatalogEvent` + +SHA-256: `3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e` + +Sources: [`packages/subagent/subagent/src/catalog.ts:24`](../packages/subagent/subagent/src/catalog.ts) + +One of: + +- [`{ childCreatedAt, childId, label, mode, … }`](#persistence-type-sha256-0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd) +- [`{ childCreatedAt, childId, label?, mode, … }`](#persistence-type-sha256-5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694) + + + + + + + +### `SubagentDescriptorData` + +SHA-256: `86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde` + +Sources: [`packages/subagent/subagent/src/descriptor.ts:89`](../packages/subagent/subagent/src/descriptor.ts) + +One of: + +- [`ContinuableSubagentDescriptorData`](#persistence-type-sha256-6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f) +- [`OneShotSubagentDescriptorData`](#persistence-type-sha256-5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564) + + + + + + + +### `SubagentSettledMessageSource` + +SHA-256: `4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a` + +Sources: [`packages/subagent/subagent/src/continuation-messages.ts:30`](../packages/subagent/subagent/src/continuation-messages.ts) + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"subagent-settled"` | +| `senderSessionId` | required | `string` | +| `summary` | required | `string` | + + + + + + + +### `SurfaceOp` + +SHA-256: `335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5` + +Sources: [`packages/core/session/src/types.ts:462`](../packages/core/session/src/types.ts) + +One of: + +- `"append"` +- [`{ endSeq, op, startSeq }`](#persistence-type-sha256-bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825) + + + + + + + +### `SystemMessage` + +SHA-256: `09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363` + +Sources: [`packages/llm/llm/src/message.ts:151`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | required | `string` | +| `role` | required | `"system"` | +| `source` | required | [`SystemPromptMessageSource`](#persistence-type-sha256-65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad) | + + + + + + + +### `SystemPromptMessageSource` + +SHA-256: `65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad` + +Sources: [`packages/llm/llm/src/message.ts:35`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"system-prompt"` | + + + + + + + +### `TeamMemberPhase` + +SHA-256: `dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd` + +Sources: [`packages/experimental/agent-team/src/types.ts:44`](../packages/experimental/agent-team/src/types.ts) + +One of: + +- `"active"` +- `"failed"` +- `"provisioning"` + + + + + + + +### `TeamMemberSnapshot` + +SHA-256: `6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25` + +Sources: [`packages/experimental/agent-team/src/types.ts:47`](../packages/experimental/agent-team/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `context` | required | [`union (2 variants)`](#persistence-type-sha256-50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48) | +| `description` | required | `string` | +| `error` | optional | `string` | +| `id` | required | `string` | +| `name` | required | `string` | +| `phase` | required | [`TeamMemberPhase`](#persistence-type-sha256-dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd) | +| `provider` | required | `string` | + + + + + + + +### `TeamMessageSnapshot` + +SHA-256: `2eafefdc6f79a4922d68a787a09eaf4dd2b2369c3777fba4c05e800b5678ac8e` + +Sources: [`packages/experimental/agent-team/src/types.ts:106`](../packages/experimental/agent-team/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | required | `string` | +| `senderId` | required | `string` | +| `senderName` | required | `string` | +| `targetId` | required | `string` | + + + + + + + +### `TeamMessageSource` + +SHA-256: `2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0` + +Sources: [`packages/experimental/agent-team/src/types.ts:115`](../packages/experimental/agent-team/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"team-message"` | +| `messageId` | required | `string` | +| `senderId` | required | `string` | +| `senderName` | required | `string` | +| `teamId` | required | `string` | + + + + + + + +### `TeamTaskSnapshot` + +SHA-256: `51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357` + +Sources: [`packages/experimental/agent-team/src/types.ts:74`](../packages/experimental/agent-team/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `blockedBy` | required | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `description` | required | `string` | +| `id` | required | `string` | +| `ownerId` | optional | `string` | +| `revision` | required | `number` | +| `status` | required | [`TeamTaskStatus`](#persistence-type-sha256-b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943) | +| `subject` | required | `string` | +| `writeScopes` | required | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | + + + + + + + +### `TeamTaskStatus` + +SHA-256: `b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943` + +Sources: [`packages/experimental/agent-team/src/types.ts:71`](../packages/experimental/agent-team/src/types.ts) + +One of: + +- `"completed"` +- `"deleted"` +- `"in_progress"` +- `"pending"` + + + + + + + +### `TextBlock` + +SHA-256: `4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c` + +Sources: [`packages/llm/llm/src/types.ts:62`](../packages/llm/llm/src/types.ts) · [`packages/web/web-search-deepseek/src/provider.ts:66`](../packages/web/web-search-deepseek/src/provider.ts) + +| Property | Presence | Type | +|---|---|---| +| `text` | required | `string` | +| `type` | required | `"text"` | + + + + + + + +### `TodoItem` + +SHA-256: `a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a` + +Sources: [`packages/todo/tool-todo/src/types.ts:21`](../packages/todo/tool-todo/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | `string` | +| `status` | required | [`union (3 variants)`](#persistence-type-sha256-fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4) | + + + +### `TodoItem[]` + +SHA-256: `4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea` + +Array of [`TodoItem`](#persistence-type-sha256-a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a). + + + + + + + +### `TokenUsage` + +SHA-256: `fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394` + +Sources: [`packages/llm/llm/src/types.ts:176`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `cacheReadTokens` | optional | `number` | +| `cacheWriteTokens` | optional | `number` | +| `inputTokens` | required | `number` | +| `outputTokens` | required | `number` | +| `reasoningTokens` | optional | `number` | +| `totalTokens` | optional | `number` | + + + + + + + +### `ToolAdditionBlock` + +SHA-256: `8e611bf46821e5003a1605a73560a6f56388295149d449dfe2142d5ec335f29c` + +Sources: [`packages/llm/llm/src/types.ts:115`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `tool` | optional | `never` | +| `toolName` | required | `string` | +| `type` | required | `"tool-addition"` | + + + + + + + +### `ToolCallBlock` + +SHA-256: `c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea` + +Sources: [`packages/llm/llm/src/types.ts:105`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `string` | +| `id` | required | `string` | +| `name` | required | `string` | +| `type` | required | `"tool-call"` | + + + + + + + +### `ToolMessageSource` + +SHA-256: `d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab` + +Sources: [`packages/llm/llm/src/message.ts:29`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `callId` | required | `string` | +| `kind` | required | `"tool"` | + + + + + + + +### `ToolRemovalBlock` + +SHA-256: `43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8` + +Sources: [`packages/llm/llm/src/types.ts:127`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `toolName` | required | `string` | +| `type` | required | `"tool-removal"` | + + + + + + + +### `ToolRestriction` + +SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f` + +Sources: [`packages/core/tools/src/index.ts:689`](../packages/core/tools/src/index.ts) + +| Property | Presence | Type | +|---|---|---| +| `allow` | optional | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `deny` | optional | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | + + + + + + + +### `ToolResultMessage` + +SHA-256: `4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731` + +Sources: [`packages/llm/llm/src/message.ts:173`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | required | `string` | +| `isError` | optional | `boolean` | +| `role` | required | `"tool"` | +| `source` | required | [`ToolMessageSource`](#persistence-type-sha256-d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab) | +| `toolCallId` | required | `string` | + + + + + + + +### `ToolSchema` + +SHA-256: `66ba70f6f068da443f969a0b947a013c3addd776b9b60a0a393759c19825e9a2` + +Sources: [`packages/llm/llm/src/types.ts:461`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `deferLoading` | optional | `true` | +| `description` | required | `string` | +| `name` | required | `string` | +| `parameters` | required | [`{}`](#persistence-type-sha256-0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f) | + + + +### `ToolSchema[]` + +SHA-256: `a0baff42eb900561f91032b6950a3925cf19c5c8d9ba33948ac69e4ac7dee573` + +Array of [`ToolSchema`](#persistence-type-sha256-66ba70f6f068da443f969a0b947a013c3addd776b9b60a0a393759c19825e9a2). + + + + + + + +### `ToolWorkflowAgentEndData` + +SHA-256: `c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7` + +Sources: [`packages/workflow/tool-workflow/src/types.ts:29`](../packages/workflow/tool-workflow/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `outcome` | required | [`WorkflowAgentOutcome`](#persistence-type-sha256-c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896) | +| `runId` | required | `string` | +| `seq` | required | `number` | + + + + + + + +### `ToolWorkflowAgentStartData` + +SHA-256: `9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc` + +Sources: [`packages/workflow/tool-workflow/src/types.ts:20`](../packages/workflow/tool-workflow/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `childId` | required | `string` | +| `label` | required | `string` | +| `phase` | optional | `string` | +| `runId` | required | `string` | +| `seq` | required | `number` | + + + + + + + +### `ToolWorkflowRunEndData` + +SHA-256: `7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462` + +Sources: [`packages/workflow/tool-workflow/src/types.ts:36`](../packages/workflow/tool-workflow/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `runId` | required | `string` | +| `stopReason` | required | [`WorkflowStopReason`](#persistence-type-sha256-8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15) | + + + + + + + +### `ToolWorkflowRunStartData` + +SHA-256: `a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c` + +Sources: [`packages/workflow/tool-workflow/src/types.ts:14`](../packages/workflow/tool-workflow/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `name` | required | `string` | +| `runId` | required | `string` | + + + + + + + +### `TurnEndCancelCause` + +SHA-256: `1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0` + +Sources: [`packages/core/session/src/types.ts:196`](../packages/core/session/src/types.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `disposed` | not declared | none | [`{ kind: "disposed" }`](#persistence-type-sha256-4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db) | +| `hook` | not declared | `reason`: `string` | [`{ kind: "hook" }`](#persistence-type-sha256-6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d) | +| `legacy` | not declared | none | [`{ kind: "legacy" }`](#persistence-type-sha256-eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c) | +| `parent` | not declared | none | [`{ kind: "parent" }`](#persistence-type-sha256-6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800) | +| `user` | not declared | none | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | + + + + + + + +### `TurnEndReason` + +SHA-256: `f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402` + +Sources: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts) + +| kind | Form property | Other required fields | Full definition | +|---|---|---|---| +| `aborted` | not declared | `reason`: [`TurnEndCancelCause`](#persistence-type-sha256-1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0) | [`{ kind: "aborted", reason }`](#persistence-type-sha256-0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3) | +| `blocked` | not declared | none | [`{ kind: "blocked" }`](#persistence-type-sha256-023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4) | +| `completed` | not declared | none | [`{ kind: "completed" }`](#persistence-type-sha256-b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0) | +| `error` | not declared | `error`: [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | [`{ error, kind: "error" }`](#persistence-type-sha256-79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985) | +| `forked` | not declared | none | [`{ kind: "forked" }`](#persistence-type-sha256-ec8b5ff7c77ca6893ac7ba5a0c5b2aefeb52f12c64450b7359660c2a7e8a53d7) | +| `interrupted` | not declared | none | [`{ kind: "interrupted" }`](#persistence-type-sha256-56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23) | +| `max-tokens` | not declared | none | [`{ kind: "max-tokens" }`](#persistence-type-sha256-ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7) | + + + + + + + +### `UserMessage` + +SHA-256: `64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586` + +Sources: [`packages/llm/llm/src/message.ts:162`](../packages/llm/llm/src/message.ts) + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | required | `string` | +| `role` | required | `"user"` | +| `source` | required | [`MessageSource`](#persistence-type-sha256-40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945) | + +Source compatibility: `source` — `session-source-attribution` v1; `session.user-message.source`; `kind`; `preserve`. + +Attribution-only additions: `tmux-context`. + + + +### `UserMessage[]` + +SHA-256: `d1f27cf1650e5f59d5d6e95ce6dfd92b31757af076a8ab6418a70b6dbdd53621` + +Array of [`UserMessage`](#persistence-type-sha256-64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586). + + + + + + + +### `WorkflowAgentOutcome` + +SHA-256: `c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896` + +Sources: [`packages/workflow/workflow/src/types.ts:110`](../packages/workflow/workflow/src/types.ts) + +One of: + +- `"cancelled"` +- `"completed"` +- `"failed"` + + + + + + + +### `WorkflowStopReason` + +SHA-256: `8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15` + +Sources: [`packages/workflow/workflow/src/types.ts:63`](../packages/workflow/workflow/src/types.ts) + +One of: + +- `"cancelled"` +- `"completed"` +- `"error"` + + + +### `boolean` + +SHA-256: `aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877` + +`boolean` + + + +### `false` + +SHA-256: `0c4205180f75b9ee1e0d878bd9a9851628b5dc18448486389d9c5fdc3f1ccda3` + +`false` + + + +### `never` + +SHA-256: `fcf427290c6213c2a7feb57492d832ce324f5b9737a759f424dab69e6bd101a0` + +`never` + + + +### `null` + +SHA-256: `938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615` + +`null` + + + + + + + +### `number` + +SHA-256: `0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7` + +Sources: [`packages/core/session/src/types.ts:32`](../packages/core/session/src/types.ts) + +`number` + + + +### `number[]` + +SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` + +Array of `number`. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +### `string` + +SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` + +Sources: [`packages/api/session-controller/src/types.ts:380`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:20`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:10`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/webhook/webhook/src/brand.ts:12`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:6`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:9`](../packages/webhook/webhook/src/brand.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) + +`string` + + + +### `string[]` + +SHA-256: `93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2` + +Array of `string`. + + + +### `true` + +SHA-256: `dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521` + +`true` + + + +### `tuple (1 positions)` + +SHA-256: `4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`{ type: "web_search_20250305" }`](#persistence-type-sha256-2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3) | + + + +### `tuple (1 positions)` + +SHA-256: `8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`TextBlock`](#persistence-type-sha256-4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c) | + + + +### `tuple (1 positions)` + +SHA-256: `b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`{ role: "user" }`](#persistence-type-sha256-9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5) | + + + +### `union (2 variants)` + +SHA-256: `1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92` + +One of: + +- `"error"` +- `"success"` + + + +### `union (2 variants)` + +SHA-256: `50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48` + +One of: + +- `"fork"` +- `"fresh"` + + + +### `union (2 variants)` + +SHA-256: `9947aa5938fe19a895298da412917acbf9ffb5093a73ab8baa257e6ae9e63a07` + +One of: + +- [`{ compactionId, llmStreamCall, maxTokens?, model, … }`](#persistence-type-sha256-a99ec0993c62c058e50af9f68922202a3b54f5e259bc2abf1915a73381d2316d) +- [`{ compactionId, maxTokens?, model, provider, … }`](#persistence-type-sha256-576a2de8355eb09850963ff5953420b172e274d9283666eb7d889097db120796) + + + + + +### `union (3 variants)` + +SHA-256: `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` + +One of: + +- [`{ ignorable?, seq, sourceEventSeqs?, surfaceOp, … }`](#persistence-type-sha256-998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0) +- [`{ ignorable?, seq, surfaceOp, time, … }`](#persistence-type-sha256-7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb) +- [`{ ignorable?, seq, time, type }`](#persistence-type-sha256-e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f) + + + +### `union (3 variants)` SHA-256: `904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd` @@ -1866,832 +5413,36 @@ One of: - `"replace"` - `"set"` - + -### `event:agent/inbox/spliced.data.inserted[0].source[17].entries` +### `union (3 variants)` -SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` - -Array of [`event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]`](#persistence-type-eventagentinboxspliceddatainserted0source17entries0). - - - -### `event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]` - -SHA-256: `83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693` - -Sources: [`packages/skill/tool-skill/src/index.ts:40`](../packages/skill/tool-skill/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| `description` | required | `string` | -| `name` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[19]` - -SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` - -Sources: [`packages/webhook/webhook/src/types.ts:74`](../packages/webhook/webhook/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `deliveryId` | required | `string` | -| `form` | required | `"notice"` | -| `kind` | required | `"webhook"` | -| `provider` | required | `string` | -| `ruleId` | required | `string` | -| `source` | required | `string` | -| `summary` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[2]` - -SHA-256: `dda6e111a8ccfc12f6e742e977a1a4e3549e8c03732a5ff6c8d7c3d4bcb7a412` - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"instructions"` | -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[3]` - -SHA-256: `2f90a7b3646fea3e677bd7b4000aa96f3b8964f107b614e204e11ad4051c24fc` - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"catalog"` | -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[4]` - -SHA-256: `e8d26e6993445743e6c4342c31b284c7d8f5574369abdd6021183af1a6b3538f` - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"snapshot"` | -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | -| `sections` | required | [`event:agent/inbox/spliced.data.inserted[0].source[4].sections`](#persistence-type-eventagentinboxspliceddatainserted0source4sections) | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[4].sections` - -SHA-256: `c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262` - -Array of [`packages/llm/llm/src/message.ts#ContextSnapshotSection`](#persistence-type-packagesllmllmsrcmessagetscontextsnapshotsection). - - - -### `event:agent/inbox/spliced.data.inserted[0].source[5]` - -SHA-256: `b4d298d90c798fa4d1f5b030ce3ce8031c4c41beafdb05323bec8b2a06903b43` - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"notice"` | -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | -| `summary` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[6]` - -SHA-256: `2ce7ef3b3daebf95815c7ae454a751d3e67ca7a22e2e0734fe2942df393bb66c` - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"relay"` | -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[7]` - -SHA-256: `85e1bd563d6c80c1f377f99f91103fec4e315148a7330f3b3dae7c2d04e33b01` - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"recall"` | -| `kind` | required | `"plugin"` | -| `plugin` | required | `string` | - - - -### `event:approval/asked` - -SHA-256: `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:approval/asked.data`](#persistence-type-eventapprovalaskeddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"approval/asked"` | - - - -### `event:approval/asked.data` - -SHA-256: `45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448` - -Sources: [`packages/interaction/user-approval/src/types.ts:44`](../packages/interaction/user-approval/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `callId` | optional | `string` | -| `id` | required | `string` | -| `reason` | optional | `string` | -| `toolName` | required | `string` | - - - -### `event:approval/decided` - -SHA-256: `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:approval/decided.data`](#persistence-type-eventapprovaldecideddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"approval/decided"` | - - - -### `event:approval/decided.data` - -SHA-256: `93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9` - -Sources: [`packages/interaction/user-approval/src/types.ts:55`](../packages/interaction/user-approval/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `id` | required | `string` | -| `outcome` | required | [`packages/interaction/user-approval/src/types.ts#ApprovalOutcome`](#persistence-type-packagesinteractionuser-approvalsrctypestsapprovaloutcome) | - - - -### `event:approval/policy` - -SHA-256: `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:approval/policy.data`](#persistence-type-eventapprovalpolicydata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"approval/policy"` | - - - -### `event:approval/policy.data` - -SHA-256: `11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912` - -Sources: [`packages/interaction/user-approval/src/index.ts:33`](../packages/interaction/user-approval/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| `policy` | required | [`packages/interaction/user-approval/src/index.ts#ApprovalPolicy`](#persistence-type-packagesinteractionuser-approvalsrcindextsapprovalpolicy) | -| `source` | optional | `"delegation"` | - - - -### `event:assistant/attempt` - -SHA-256: `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:assistant/attempt.data`](#persistence-type-eventassistantattemptdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"assistant/attempt"` | - - - -### `event:assistant/attempt.data` - -SHA-256: `0c6412d3ba5e41adfaa6929c7d4093f2d52d8598c03f35844fc0d55e3070a3b1` - -Sources: [`packages/core/session/src/types.ts:335`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `step` | required | `number` | -| `stream` | required | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | -| `turn` | required | `number` | - - - -### `event:assistant/attempt.data.stream` - -SHA-256: `26f3bb7529cfce1e3a0f1ededa365d8b426758ca0feeb0beabeee805f8bb8346` - -Array of [`packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord`](#persistence-type-packagesllmllmsrcassistant-streamtsassistantstreamrecord). - - - -### `event:assistant/attempt.data.stream[0][0]` - -SHA-256: `e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33` - -Sources: [`packages/llm/llm/src/assistant-stream.ts:21`](../packages/llm/llm/src/assistant-stream.ts) - -| Property | Presence | Type | -|---|---|---| -| `dt` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `index` | required | `number` | -| `texts` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `time0` | required | `number` | -| `type` | required | `"text-chunks"` | - - - -### `event:assistant/attempt.data.stream[0][0].texts` - -SHA-256: `93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2` - -Array of `string`. - - - -### `event:assistant/attempt.data.stream[0][1]` - -SHA-256: `71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd` - -Sources: [`packages/llm/llm/src/assistant-stream.ts:28`](../packages/llm/llm/src/assistant-stream.ts) - -| Property | Presence | Type | -|---|---|---| -| `dt` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `index` | required | `number` | -| `texts` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `time0` | required | `number` | -| `type` | required | `"reasoning-chunks"` | - - - -### `event:assistant/attempt.data.stream[0][2]` - -SHA-256: `3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6` - -Sources: [`packages/llm/llm/src/assistant-stream.ts:35`](../packages/llm/llm/src/assistant-stream.ts) - -| Property | Presence | Type | -|---|---|---| -| `args` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `dt` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `id` | required | `string` | -| `index` | required | `number` | -| `name` | optional | `string` | -| `time0` | required | `number` | -| `type` | required | `"tool-call-chunks"` | - - - -### `event:assistant/attempt.data.stream[0][3]` - -SHA-256: `c93b6f51b399607349b4bcc66b58e848a44250ffc1e2537207bd092dfff94192` - -Sources: [`packages/llm/llm/src/assistant-stream.ts:44`](../packages/llm/llm/src/assistant-stream.ts) - -| Property | Presence | Type | -|---|---|---| -| `chunk` | required | [`packages/llm/llm/src/types.ts#StreamChunk`](#persistence-type-packagesllmllmsrctypestsstreamchunk) | -| `time` | required | `number` | -| `type` | required | `"chunk"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[0]` - -SHA-256: `647cb2e3aeb58e27d1d4d60011f208bb66dce257e8654193c533b47c4c22c253` - -Sources: [`packages/llm/llm/src/types.ts:427`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `blockType` | required | [`packages/llm/llm/src/types.ts#ContentBlockType`](#persistence-type-packagesllmllmsrctypestscontentblocktype) | -| `index` | required | `number` | -| `type` | required | `"block-start"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[1]` - -SHA-256: `95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65` - -Sources: [`packages/llm/llm/src/types.ts:428`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `index` | required | `number` | -| `text` | required | `string` | -| `type` | required | `"text-delta"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[2]` - -SHA-256: `2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095` - -Sources: [`packages/llm/llm/src/types.ts:429`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `index` | required | `number` | -| `text` | required | `string` | -| `type` | required | `"reasoning-delta"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[3]` - -SHA-256: `88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a` - -Sources: [`packages/llm/llm/src/types.ts:430`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `argumentsDelta` | required | `string` | -| `id` | required | `string` | -| `index` | required | `number` | -| `name` | optional | `string` | -| `type` | required | `"tool-call-delta"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[4]` - -SHA-256: `90c811b8c2668898515e69a24e82caffeb08517f9c7aa193867ff0380f3b535d` - -Sources: [`packages/llm/llm/src/types.ts:431`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `block` | required | [`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock) | -| `index` | required | `number` | -| `type` | required | `"block-end"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[5]` - -SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515` - -Sources: [`packages/llm/llm/src/types.ts:432`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `type` | required | `"usage"` | -| `usage` | required | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6]` - -SHA-256: `a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1` - -Sources: [`packages/llm/llm/src/types.ts:433`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `reason` | required | [`packages/llm/llm/src/types.ts#FinishReason`](#persistence-type-packagesllmllmsrctypestsfinishreason) | -| `replayState` | optional | [`packages/llm/llm/src/types.ts#ReplayEnvelope`](#persistence-type-packagesllmllmsrctypestsreplayenvelope) | -| `type` | required | `"finish"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]` - -SHA-256: `8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0` - -Sources: [`packages/llm/llm/src/types.ts:147`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | -| `kind` | required | `"aborted"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]` - -SHA-256: `693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057` - -Sources: [`packages/llm/llm/src/types.ts:148`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | -| `kind` | required | `"error"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]` - -SHA-256: `ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7` - -Sources: [`packages/core/session/src/types.ts:213`](../packages/core/session/src/types.ts) · [`packages/llm/llm/src/types.ts:146`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"max-tokens"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]` - -SHA-256: `1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f` - -Sources: [`packages/llm/llm/src/types.ts:144`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"stop"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]` - -SHA-256: `287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a` - -Sources: [`packages/llm/llm/src/types.ts:145`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"tool-calls"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks` - -SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7` - -Array of `unknown` (opaque). - - - -### `event:assistant/message` - -SHA-256: `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:assistant/message.data`](#persistence-type-eventassistantmessagedata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | required | `number` | -| `type` | required | `"assistant/message"` | - - - -### `event:assistant/message.data` - -SHA-256: `77b8491f946edfc8cc77ebae3ba49183759da31ba2dfa83d4c9e9e618c4b91d2` - -Sources: [`packages/core/session/src/types.ts:321`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `interrupted` | optional | `true` | -| `message` | required | [`packages/llm/llm/src/message.ts#AssistantMessage`](#persistence-type-packagesllmllmsrcmessagetsassistantmessage) | -| `step` | required | `number` | -| `stream` | required | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | -| `turn` | required | `number` | -| `usage` | optional | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:command/done` - -SHA-256: `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:command/done.data`](#persistence-type-eventcommanddonedata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"command/done"` | - - - -### `event:command/done.data` - -SHA-256: `5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51` - -Sources: [`packages/interaction/commands/src/types.ts:112`](../packages/interaction/commands/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `commandId` | required | `string` | -| `kind` | required | [`event:command/done.data.kind`](#persistence-type-eventcommanddonedatakind) | -| `sourceEventSeq` | optional | `number` | -| `text` | optional | `string` | - - - -### `event:command/done.data.kind` - -SHA-256: `1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92` +SHA-256: `fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4` One of: -- `"error"` -- `"success"` +- `"completed"` +- `"in_progress"` +- `"pending"` - + -### `event:command/run` +### `union (6 variants)` -SHA-256: `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:command/run.data`](#persistence-type-eventcommandrundata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"command/run"` | - - - -### `event:command/run.data` - -SHA-256: `a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86` - -Sources: [`packages/interaction/commands/src/types.ts:105`](../packages/interaction/commands/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `args` | optional | `string` | -| `commandId` | required | `string` | -| `name` | required | `string` | -| `source` | required | [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) | - - - -### `event:compaction/end` - -SHA-256: `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:compaction/end.data`](#persistence-type-eventcompactionenddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"compaction/end"` | - - - -### `event:compaction/end.data` - -SHA-256: `ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2` - -Sources: [`packages/compaction/compaction/src/types.ts:72`](../packages/compaction/compaction/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `compactionId` | required | `string` | -| `error` | optional | `string` | -| `sourceCommandId` | optional | `string` | -| `turn` | required | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | - - - -### `event:compaction/end.data.turn` - -SHA-256: `3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f` - -Sources: [`packages/core/session/src/types.ts:64`](../packages/core/session/src/types.ts) +SHA-256: `62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379` One of: -- `null` -- `number` +- `"block"` +- `"complete"` +- `"create"` +- `"edit"` +- `"pause"` +- `"resume"` - + -### `event:compaction/prune` - -SHA-256: `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:compaction/prune.data`](#persistence-type-eventcompactionprunedata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"compaction/prune"` | - - - -### `event:compaction/prune.data` - -SHA-256: `5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438` - -Sources: [`packages/compaction/compaction/src/types.ts:82`](../packages/compaction/compaction/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `shadowedRange` | required | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | -| `shadowedSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `shadowedTokenCount` | required | `number` | - - - -### `event:compaction/prune.data.shadowedRange` - -SHA-256: `9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2` - -Sources: [`packages/compaction/compaction/src/types.ts:38`](../packages/compaction/compaction/src/types.ts) · [`packages/compaction/compaction/src/types.ts:84`](../packages/compaction/compaction/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `end` | required | `number` | -| `start` | required | `number` | - - - -### `event:compaction/start` - -SHA-256: `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:compaction/start.data`](#persistence-type-eventcompactionstartdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"compaction/start"` | - - - -### `event:compaction/start.data` - -SHA-256: `3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f` - -Sources: [`packages/compaction/compaction/src/types.ts:24`](../packages/compaction/compaction/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `compactionId` | required | `string` | -| `sourceCommandId` | optional | `string` | -| `turn` | required | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | - - - -### `event:compaction/summary` - -SHA-256: `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:compaction/summary.data`](#persistence-type-eventcompactionsummarydata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"compaction/summary"` | - - - -### `event:compaction/summary.data` - -SHA-256: `feb329074f0206ecc06d8a1aa0a0b3e2f47fd27524ba020fbc849ba63e938896` - -One of: - -- [`event:compaction/summary.data[0]`](#persistence-type-eventcompactionsummarydata0) -- [`event:compaction/summary.data[1]`](#persistence-type-eventcompactionsummarydata1) - - - -### `event:compaction/summary.data[0]` - -SHA-256: `9ff2ad8dddb836f75e8f6197fff2371323dfc396c3c6fb667e6e0b42fda79a5c` - -| Property | Presence | Type | -|---|---|---| -| `compactionId` | required | `string` | -| `llmStreamCall` | required | `true` | -| `maxTokens` | optional | `number` | -| `model` | required | `string` | -| `provider` | required | `string` | -| `rawOutput` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `shadowedRange` | required | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | -| `shadowedSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `shadowedTokenCount` | required | `number` | -| `sourceCommandId` | optional | `string` | -| `summary` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `usage` | optional | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:compaction/summary.data[1]` - -SHA-256: `3aa261c8516b5c955ed12080e6257a56cbe513f6c9f0ac9274c12e96c196ebca` - -| Property | Presence | Type | -|---|---|---| -| `compactionId` | required | `string` | -| `maxTokens` | optional | `number` | -| `model` | required | `string` | -| `provider` | required | `string` | -| `rawOutput` | optional | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `shadowedRange` | required | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | -| `shadowedSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `shadowedTokenCount` | required | `number` | -| `sourceCommandId` | optional | `string` | -| `summary` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `usage` | optional | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:deliverables/presented` - -SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:deliverables/presented.data`](#persistence-type-eventdeliverablespresenteddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"deliverables/presented"` | - - - -### `event:deliverables/presented.data` - -SHA-256: `1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c` - -Sources: [`packages/deliverables/tool-present/src/types.ts:15`](../packages/deliverables/tool-present/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `callId` | required | `string` | -| `files` | required | [`event:deliverables/presented.data.files`](#persistence-type-eventdeliverablespresenteddatafiles) | -| `turn` | required | `number` | - - - -### `event:deliverables/presented.data.files` - -SHA-256: `1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345` - -Array of [`packages/deliverables/tool-present/src/types.ts#PresentedFile`](#persistence-type-packagesdeliverablestool-presentsrctypestspresentedfile). - - - -### `event:feedback/message-delete` - -SHA-256: `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackdelete) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"feedback/message-delete"` | - - - -### `event:feedback/message-put` - -SHA-256: `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackput) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"feedback/message-put"` | - - - -### `event:feedback/message-put.data.item.category` +### `union (7 variants)` SHA-256: `3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd` @@ -2705,96 +5456,278 @@ One of: - `"service-stability"` - `"task-result"` - + -### `event:feedback/record` +### `unknown` -SHA-256: `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` +SHA-256: `bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d` + +`unknown`: the declaration does not expose the stored value's internal fields. + + + +### `unknown[]` + +SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7` + +Array of `unknown` (opaque). + + + +### `{ active }` + +SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5` + +Sources: [`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/feedback/command-feedback/src/types.ts#FeedbackRecord`](#persistence-type-packagesfeedbackcommand-feedbacksrctypestsfeedbackrecord) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"feedback/record"` | +| `active` | required | `boolean` | - + -### `event:goal/change` +### `{ agentPreset }` -SHA-256: `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` +SHA-256: `6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406` + +Sources: [`packages/preset/agent-presets/src/session.ts:28`](../packages/preset/agent-presets/src/session.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/goal/goal/src/domain.ts#GoalChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalchangemeta) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"goal/change"` | +| `agentPreset` | required | `string` | - + -### `event:goal/change.data[0].operation` +### `{ allowedModels }` -SHA-256: `62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379` +SHA-256: `0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f` -One of: - -- `"block"` -- `"complete"` -- `"create"` -- `"edit"` -- `"pause"` -- `"resume"` - - - -### `event:hook/invoked` - -SHA-256: `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` +Sources: [`packages/subagent/tool-subagent/src/model-selection-state.ts:17`](../packages/subagent/tool-subagent/src/model-selection-state.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:hook/invoked.data`](#persistence-type-eventhookinvokeddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"hook/invoked"` | +| `allowedModels` | required | [`SessionTitleModelIdentity[]`](#persistence-type-sha256-ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec) | - + -### `event:hook/invoked.data` +### `{ args?, commandId, name, source }` -SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` +SHA-256: `a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86` -Sources: [`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) +Sources: [`packages/interaction/commands/src/types.ts:105`](../packages/interaction/commands/src/types.ts) | Property | Presence | Type | |---|---|---| -| `dialect` | required | [`packages/hooks/hook-protocol/src/types.ts#HookDialect`](#persistence-type-packageshookshook-protocolsrctypestshookdialect) | -| `handlerId` | required | `string` | -| `matcher` | optional | `string` | -| `point` | required | `string` | +| `args` | optional | `string` | +| `commandId` | required | `string` | +| `name` | required | `string` | +| `source` | required | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | + + + +### `{ arguments, callId, name, step, … }` + +SHA-256: `e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1` + +Sources: [`packages/core/session/src/types.ts:361`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `string` | +| `callId` | required | `string` | +| `name` | required | `string` | +| `step` | required | `number` | | `turn` | required | `number` | - + -### `event:hook/result` +### `{ callId, files, turn }` -SHA-256: `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` +SHA-256: `1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c` + +Sources: [`packages/deliverables/tool-present/src/types.ts:15`](../packages/deliverables/tool-present/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:hook/result.data`](#persistence-type-eventhookresultdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"hook/result"` | +| `callId` | required | `string` | +| `files` | required | [`PresentedFile[]`](#persistence-type-sha256-1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345) | +| `turn` | required | `number` | - + -### `event:hook/result.data` +### `{ callId?, id, reason?, toolName }` + +SHA-256: `45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448` + +Sources: [`packages/interaction/user-approval/src/types.ts:44`](../packages/interaction/user-approval/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `callId` | optional | `string` | +| `id` | required | `string` | +| `reason` | optional | `string` | +| `toolName` | required | `string` | + + + +### `{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }` + +SHA-256: `4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4` + +Sources: [`packages/context/session-reference/src/types.ts:18`](../packages/context/session-reference/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `capturedFormatVersion` | optional | `number` | +| `capturedThroughSeq` | required | [`OptionalSessionSeq`](#persistence-type-sha256-3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f) | +| `compacted` | required | `boolean` | +| `inputIndex` | required | `number` | +| `label` | required | `string` | +| `omittedBytes` | required | `number` | +| `omittedMessages` | required | `number` | +| `originalMessages` | required | `number` | +| `retainedMessages` | required | `number` | +| `sessionId` | required | `string` | +| `truncated` | required | `boolean` | + + + +### `{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }[]` + +SHA-256: `df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18` + +Array of [`{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }`](#persistence-type-sha256-4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4). + + + +### `{ childCreatedAt, childId, label, mode, … }` + +SHA-256: `0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd` + +| Property | Presence | Type | +|---|---|---| +| `childCreatedAt` | required | `number` | +| `childId` | required | `string` | +| `label` | required | `string` | +| `mode` | required | `"continuable"` | +| `version` | required | `0` | + + + +### `{ childCreatedAt, childId, label?, mode, … }` + +SHA-256: `5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694` + +| Property | Presence | Type | +|---|---|---| +| `childCreatedAt` | required | `number` | +| `childId` | required | `string` | +| `label` | optional | `string` | +| `mode` | required | `"one-shot"` | +| `version` | required | `0` | + + + +### `{ code, name, reason? }` + +SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735` + +Sources: [`packages/core/session/src/types.ts:383`](../packages/core/session/src/types.ts) · [`packages/core/tools/src/types.ts:24`](../packages/core/tools/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `code` | required | `string` | +| `name` | required | `string` | +| `reason` | optional | `string` | + + + +### `{ commandId, kind, sourceEventSeq?, text? }` + +SHA-256: `5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51` + +Sources: [`packages/interaction/commands/src/types.ts:112`](../packages/interaction/commands/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `commandId` | required | `string` | +| `kind` | required | [`union (2 variants)`](#persistence-type-sha256-1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92) | +| `sourceEventSeq` | optional | `number` | +| `text` | optional | `string` | + + + +### `{ compactionId, error?, sourceCommandId?, turn }` + +SHA-256: `ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2` + +Sources: [`packages/compaction/compaction/src/types.ts:72`](../packages/compaction/compaction/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `error` | optional | `string` | +| `sourceCommandId` | optional | `string` | +| `turn` | required | [`OptionalSessionSeq`](#persistence-type-sha256-3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f) | + + + +### `{ compactionId, llmStreamCall, maxTokens?, model, … }` + +SHA-256: `a99ec0993c62c058e50af9f68922202a3b54f5e259bc2abf1915a73381d2316d` + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `llmStreamCall` | required | `true` | +| `maxTokens` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `rawOutput` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `shadowedRange` | required | [`{ end, start }`](#persistence-type-sha256-9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2) | +| `shadowedSeqs` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `shadowedTokenCount` | required | `number` | +| `sourceCommandId` | optional | `string` | +| `summary` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `usage` | optional | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | + + + +### `{ compactionId, maxTokens?, model, provider, … }` + +SHA-256: `576a2de8355eb09850963ff5953420b172e274d9283666eb7d889097db120796` + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `maxTokens` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `rawOutput` | optional | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `shadowedRange` | required | [`{ end, start }`](#persistence-type-sha256-9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2) | +| `shadowedSeqs` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `shadowedTokenCount` | required | `number` | +| `sourceCommandId` | optional | `string` | +| `summary` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `usage` | optional | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | + + + +### `{ compactionId, sourceCommandId?, turn }` + +SHA-256: `3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f` + +Sources: [`packages/compaction/compaction/src/types.ts:24`](../packages/compaction/compaction/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `sourceCommandId` | optional | `string` | +| `turn` | required | [`OptionalSessionSeq`](#persistence-type-sha256-3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f) | + + + +### `{ decision, durationMs, exitCode?, handlerId, … }` SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` @@ -2810,71 +5743,9 @@ Sources: [`packages/hooks/hook-protocol/src/types.ts:31`](../packages/hooks/hook | `stderrSummary` | optional | `string` | | `turn` | required | `number` | - + -### `event:image/offload` - -SHA-256: `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:image/offload.data`](#persistence-type-eventimageoffloaddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"image/offload"` | - - - -### `event:image/offload.data` - -SHA-256: `477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028` - -Sources: [`packages/compaction/compaction-image-offload/src/projection.ts:25`](../packages/compaction/compaction-image-offload/src/projection.ts) - -| Property | Presence | Type | -|---|---|---| -| `targets` | required | [`event:image/offload.data.targets`](#persistence-type-eventimageoffloaddatatargets) | - - - -### `event:image/offload.data.targets` - -SHA-256: `9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb` - -Array of [`packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget`](#persistence-type-packagescompactioncompaction-image-offloadsrcprojectiontsimageoffloadtarget). - - - -### `event:llm/retry` - -SHA-256: `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/llm/llm-retry/src/types.ts#LlmRetryEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretryeventdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"llm/retry"` | - - - -### `event:llm/retry-started` - -SHA-256: `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretrystartedeventdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"llm/retry-started"` | - - - -### `event:llm/retry.data[0]` +### `{ delayMs, failure, maxRetries, mode, … }` SHA-256: `cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced` @@ -2883,7 +5754,7 @@ Sources: [`packages/llm/llm-retry/src/types.ts:17`](../packages/llm/llm-retry/sr | Property | Presence | Type | |---|---|---| | `delayMs` | required | `number` | -| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `failure` | required | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | | `maxRetries` | required | `number` | | `mode` | required | `"normal"` | | `policyKey` | required | `string` | @@ -2893,9 +5764,9 @@ Sources: [`packages/llm/llm-retry/src/types.ts:17`](../packages/llm/llm-retry/sr | `step` | required | `number` | | `turn` | required | `number` | - + -### `event:llm/retry.data[1]` +### `{ delayMs, failure, mode, policyKey, … }` SHA-256: `374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b` @@ -2904,7 +5775,7 @@ Sources: [`packages/llm/llm-retry/src/types.ts:30`](../packages/llm/llm-retry/sr | Property | Presence | Type | |---|---|---| | `delayMs` | required | `number` | -| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `failure` | required | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | | `mode` | required | `"always"` | | `policyKey` | required | `string` | | `provider` | required | `string` | @@ -2913,278 +5784,409 @@ Sources: [`packages/llm/llm-retry/src/types.ts:30`](../packages/llm/llm-retry/sr | `step` | required | `number` | | `turn` | required | `number` | - + -### `event:model/selection` +### `{ description, name }` -SHA-256: `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` +SHA-256: `83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693` + +Sources: [`packages/skill/tool-skill/src/index.ts:40`](../packages/skill/tool-skill/src/index.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/api/session-controller/src/types.ts#ModelSelection`](#persistence-type-packagesapisession-controllersrctypestsmodelselection) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"model/selection"` | +| `description` | required | `string` | +| `name` | required | `string` | - + -### `event:permission/preset` +### `{ description, name }[]` -SHA-256: `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` +SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` + +Array of [`{ description, name }`](#persistence-type-sha256-83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693). + + + +### `{ dialect, handlerId, matcher?, point, … }` + +SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` + +Sources: [`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:permission/preset.data`](#persistence-type-eventpermissionpresetdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"permission/preset"` | +| `dialect` | required | [`HookDialect`](#persistence-type-sha256-a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb) | +| `handlerId` | required | `string` | +| `matcher` | optional | `string` | +| `point` | required | `string` | +| `turn` | required | `number` | - + -### `event:permission/preset.data` +### `{ end, start }` -SHA-256: `8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad` +SHA-256: `9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2` -Sources: [`packages/interaction/permission-presets/src/index.ts:57`](../packages/interaction/permission-presets/src/index.ts) +Sources: [`packages/compaction/compaction/src/types.ts:38`](../packages/compaction/compaction/src/types.ts) · [`packages/compaction/compaction/src/types.ts:84`](../packages/compaction/compaction/src/types.ts) | Property | Presence | Type | |---|---|---| -| `preset` | required | `string` | +| `end` | required | `number` | +| `start` | required | `number` | - + -### `event:plan/mode` +### `{ endSeq, op, startSeq }` -SHA-256: `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` +SHA-256: `bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825` + +Sources: [`packages/core/session/src/types.ts:464`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:plan/mode.data`](#persistence-type-eventplanmodedata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"plan/mode"` | +| `endSeq` | required | `number` | +| `op` | required | `"replace"` | +| `startSeq` | required | `number` | - + -### `event:plan/mode.data` +### `{ error, kind: "error" }` -SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5` +SHA-256: `79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985` -Sources: [`packages/plan/plan-mode/src/index.ts:47`](../packages/plan/plan-mode/src/index.ts) +Sources: [`packages/core/session/src/types.ts:212`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| `active` | required | `boolean` | +| `error` | required | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | +| `kind` | required | `"error"` | - + -### `event:request/context` +### `{ error?, message, meta?, step, … }` -SHA-256: `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` +SHA-256: `5302e763151277614b97e77f00e3b326694c6c1247b916a20503c344dc970777` + +Sources: [`packages/core/session/src/types.ts:375`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/core/session/src/types.ts#RequestContext`](#persistence-type-packagescoresessionsrctypestsrequestcontext) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"request/context"` | +| `error` | optional | [`{ code, name, reason? }`](#persistence-type-sha256-a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735) | +| `message` | required | [`ToolResultMessage`](#persistence-type-sha256-4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731) | +| `meta` | optional | [`JsonValue`](#persistence-type-sha256-c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6) | +| `step` | required | `number` | +| `turn` | required | `number` | - + -### `event:request/header` +### `{ failure, kind: "aborted" }` -SHA-256: `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` +SHA-256: `8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0` + +Sources: [`packages/llm/llm/src/types.ts:161`](../packages/llm/llm/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:request/header.data`](#persistence-type-eventrequestheaderdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"request/header"` | +| `failure` | required | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | +| `kind` | required | `"aborted"` | - + -### `event:request/header.data` +### `{ failure, kind: "error" }` -SHA-256: `2f0aefb72ab453c4bf21a6687f436775d359dc6f8f10410fd4c0615b20bd9d76` +SHA-256: `693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057` -Sources: [`packages/core/session/src/types.ts:370`](../packages/core/session/src/types.ts) +Sources: [`packages/llm/llm/src/types.ts:162`](../packages/llm/llm/src/types.ts) | Property | Presence | Type | |---|---|---| -| `header` | required | [`packages/core/session/src/types.ts#EpochHeader`](#persistence-type-packagescoresessionsrctypestsepochheader) | -| `reason` | required | [`packages/core/session/src/types.ts#RequestHeaderReason`](#persistence-type-packagescoresessionsrctypestsrequestheaderreason) | +| `failure` | required | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | +| `kind` | required | `"error"` | + + + +### `{ header, reason, startsSeries? }` + +SHA-256: `ad0c38a0adb82a94c925456df41586d9b5f9202fca18593eae2213d4445b4585` + +Sources: [`packages/core/session/src/types.ts:390`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `header` | required | [`EpochHeader`](#persistence-type-sha256-9a930283b91d493d6347146f2475bb107294b379415ca02162354f46a64164f7) | +| `reason` | required | [`RequestHeaderReason`](#persistence-type-sha256-530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6) | | `startsSeries` | optional | `true` | - + -### `event:request/header.data.header.tools` +### `{ headerSeq?, message, step, turn }` -SHA-256: `6d63f25a28b70801937a46b1058be5f52d4efbaf3516141470463ae469b59c23` +SHA-256: `51c78ccc9023ce6642d07fb9a10cbf942ff7e313d5b304ddc77218df71da708f` -Array of [`packages/llm/llm/src/types.ts#ToolSchema`](#persistence-type-packagesllmllmsrctypeststoolschema). - - - -### `event:request/header.data.header.tools[0].parameters` - -SHA-256: `0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f` +Sources: [`packages/core/session/src/types.ts:311`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| [`string`] | index signature | `unknown` (opaque) | +| `headerSeq` | optional | `number` | +| `message` | required | [`DeveloperMessage`](#persistence-type-sha256-f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b) | +| `step` | required | `number` | +| `turn` | required | `number` | - + -### `event:sandbox/mode` +### `{ height, width }` -SHA-256: `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` +SHA-256: `0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef` + +Sources: [`packages/attachment/attachment/src/types.ts:28`](../packages/attachment/attachment/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `height` | required | `number` | +| `width` | required | `number` | + + + +### `{ id, outcome }` + +SHA-256: `93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9` + +Sources: [`packages/interaction/user-approval/src/types.ts:55`](../packages/interaction/user-approval/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `outcome` | required | [`ApprovalOutcome`](#persistence-type-sha256-930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7) | + + + +### `{ ignorable?, seq, sourceEventSeqs?, surfaceOp, … }` + +SHA-256: `998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0` + +| Property | Presence | Type | +|---|---|---| +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `string` | + + + +### `{ ignorable?, seq, surfaceOp, time, … }` + +SHA-256: `7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb` + +| Property | Presence | Type | +|---|---|---| +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `string` | + + + +### `{ ignorable?, seq, time, type }` + +SHA-256: `e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f` | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:sandbox/mode.data`](#persistence-type-eventsandboxmodedata) | | `ignorable` | optional | `true` | | `seq` | required | `number` | | `time` | required | `number` | -| `type` | required | `"sandbox/mode"` | +| `type` | required | `string` | - + -### `event:sandbox/mode.data` - -SHA-256: `9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e` - -Sources: [`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/sandbox/sandbox-policy/src/session-mode.ts) - -| Property | Presence | Type | -|---|---|---| -| `mode` | required | [`packages/sandbox/sandbox/src/index.ts#SandboxMode`](#persistence-type-packagessandboxsandboxsrcindextssandboxmode) | -| `source` | optional | `"delegation"` | - - - -### `event:schedule/change` - -SHA-256: `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/schedule/schedule/src/types.ts#ScheduleChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulechange) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"schedule/change"` | - - - -### `event:session-log-deepseek/delivery-accepted` - -SHA-256: `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:session-log-deepseek/delivery-accepted.data`](#persistence-type-eventsession-log-deepseekdelivery-accepteddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"session-log-deepseek/delivery-accepted"` | - - - -### `event:session-log-deepseek/delivery-accepted.data` - -SHA-256: `8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52` - -Sources: [`packages/session/session-log-deepseek/src/types.ts:81`](../packages/session/session-log-deepseek/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `sessionFormatVersion` | optional | `number` | -| `sessionId` | required | `string` | -| `throughSeq` | required | `number` | - - - -### `event:session/end-seed` - -SHA-256: `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:session/end-seed.data`](#persistence-type-eventsessionend-seeddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"session/end-seed"` | - - - -### `event:session/end-seed.data` +### `{ inherited? }` SHA-256: `17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3` -Sources: [`packages/core/session/src/types.ts:405`](../packages/core/session/src/types.ts) +Sources: [`packages/core/session/src/types.ts:427`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| | `inherited` | optional | `true` | - + -### `event:session/title` +### `{ inserted, outcome?, removedCount?, start, … }` -SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` +SHA-256: `dc4bd7ac827f4b1f9236f9a157a4b4cc171a0588064a611e43edd95f62c68130` + +Sources: [`packages/core/agent/src/types.ts:87`](../packages/core/agent/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/session/session-title/src/types.ts#SessionTitleEventData`](#persistence-type-packagessessionsession-titlesrctypestssessiontitleeventdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"session/title"` | +| `inserted` | required | [`UserMessage[]`](#persistence-type-sha256-d1f27cf1650e5f59d5d6e95ce6dfd92b31757af076a8ab6418a70b6dbdd53621) | +| `outcome` | optional | `"canceled"` | +| `removedCount` | optional | `number` | +| `start` | required | `number` | +| `target` | required | [`InboxTarget`](#persistence-type-sha256-96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c) | - + -### `event:session/title-llm-request` +### `{ interrupted?, message, step, stream, … }` -SHA-256: `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` +SHA-256: `1ccb56061942f5ccb0d30c9e4f2883b9d115ff906560029de637b61d3cde896d` + +Sources: [`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData`](#persistence-type-packagessessionsession-title-llmsrcindextssessiontitlellmrequesteventdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"session/title-llm-request"` | +| `interrupted` | optional | `true` | +| `message` | required | [`AssistantMessage`](#persistence-type-sha256-fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be) | +| `step` | required | `number` | +| `stream` | required | [`AssistantStreamRecord[]`](#persistence-type-sha256-84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7) | +| `turn` | required | `number` | +| `usage` | optional | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | - + -### `event:session/title-llm-request.data.messages` +### `{ kind: "aborted", reason }` -SHA-256: `478738df7e7d2b103b09fb937817a9302c81076809f2b341169e00a9419c5665` +SHA-256: `0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3` -Array of [`packages/llm/llm/src/message.ts#Message`](#persistence-type-packagesllmllmsrcmessagetsmessage). +Sources: [`packages/core/session/src/types.ts:204`](../packages/core/session/src/types.ts) - +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"aborted"` | +| `reason` | required | [`TurnEndCancelCause`](#persistence-type-sha256-1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0) | -### `event:session/title-llm-request.data.messages[0].role` + -SHA-256: `acd36e1717d2b4ef9e98a8e6fac17ca1203f3f448e5bca51677f129a8f4999e2` +### `{ kind: "blocked" }` -One of: +SHA-256: `023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4` -- `"assistant"` -- `"system"` -- `"user"` +Sources: [`packages/core/session/src/types.ts:206`](../packages/core/session/src/types.ts) - +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"blocked"` | -### `event:session/title.data.source[0]` + + +### `{ kind: "completed" }` + +SHA-256: `b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0` + +Sources: [`packages/core/session/src/types.ts:202`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"completed"` | + + + +### `{ kind: "cordis-host-runner" }` + +SHA-256: `02b2c23f2d94b028c9588a8faace3fce1217405db346da3389368b495457bf79` + +Sources: [`packages/extensions/cordis-host-runner/src/index.ts:14`](../packages/extensions/cordis-host-runner/src/index.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"cordis-host-runner"` | + + + +### `{ kind: "disposed" }` + +SHA-256: `4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db` + +Sources: [`packages/core/session/src/types.ts:193`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"disposed"` | + + + +### `{ kind: "dsh-session-title-llm" }` + +SHA-256: `290f32bfd81ff85a8095886a8066fae06e885942b63a8bcd6a8d66d328445808` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "catalog" }` + +SHA-256: `80677c8c8b804189a0fde8aa70dd4ad7af8bb12dfd03027e8e023c8592c838bc` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "instructions" }` + +SHA-256: `224aa11d4d5f88c450822d01b99e6ca5e3a9c7f26a5ede10bae33384a09ef4dc` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "notice" }` + +SHA-256: `8338ee303e2bd448e9e6144069942f63e3cfd5868962bddc9347d7009e8919d6` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"dsh-session-title-llm"` | +| `summary` | required | `string` | + + + +### `{ kind: "dsh-session-title-llm", form: "recall" }` + +SHA-256: `b2a5c8c008a31e3dc6c3013502f2356aca13894b31c8e70601fa92f2d40d1dba` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "relay" }` + +SHA-256: `7eaef7a763ba5b949b8464bc8add8980a3a5ab566014b69787aeba71e5dfe07b` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "snapshot" }` + +SHA-256: `ba4c40b4381e0dcdfab8fc9fc75b5c9b3e8f09ef56deeb1bec8e703b0ef8cd6d` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"dsh-session-title-llm"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "fallback" }` SHA-256: `1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597` @@ -3194,9 +6196,394 @@ Sources: [`packages/session/session-title/src/types.ts:29`](../packages/session/ |---|---|---| | `kind` | required | `"fallback"` | - + -### `event:session/title.data.source[1]` +### `{ kind: "forked" }` + +SHA-256: `ec8b5ff7c77ca6893ac7ba5a0c5b2aefeb52f12c64450b7359660c2a7e8a53d7` + +Sources: [`packages/core/session/src/types.ts:228`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"forked"` | + + + +### `{ kind: "hook" }` + +SHA-256: `6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d` + +Sources: [`packages/core/session/src/types.ts:192`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"hook"` | +| `reason` | required | `string` | + + + +### `{ kind: "hooks-claude-code" }` + +SHA-256: `0ed8d1108fe7a5e1c3078ef1faea12199a56b6b1216ccaceb0f6103b0c9a7691` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "catalog" }` + +SHA-256: `297fbd8067d7815adae02b89790ec6ff5fb7c2cb0d0eb026e1746c24ec857761` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "instructions" }` + +SHA-256: `b70f3e81fe11b7a5f2504fb47a4502fb8d9c8f0731fdfe8ddcaf9b41f5a6e196` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "notice" }` + +SHA-256: `edbbfff1128099fda7b792c56330d2cb04debc9790988e66d1c3f4026e813e0e` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"hooks-claude-code"` | +| `summary` | required | `string` | + + + +### `{ kind: "hooks-claude-code", form: "recall" }` + +SHA-256: `87b1a33564b9a4d63b00988a524c12259243953aebb9c9a05127d87b27464df9` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "relay" }` + +SHA-256: `6ea608bdc8a7a63d3d23b84c49721325094db88d136482e43a820945295eee3e` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "snapshot" }` + +SHA-256: `3bdb8dc6989655b0d4ec361edafb8e2629bc263e1ea591819414fdafc1a413b3` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"hooks-claude-code"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "hooks-codex" }` + +SHA-256: `b4ec0af39fd52ed971990e42f04e5be3204882e555c409eb330f8238eec21569` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "catalog" }` + +SHA-256: `99f0e98184709ad10f27bfdeaafb4457d9d2b413f402331764798cdb7d3cbe4d` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "instructions" }` + +SHA-256: `b6f94c17dd9bbd7cd57015198b7c7c88407f0e3b89faab176ca3c11c3d864d3e` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "notice" }` + +SHA-256: `854db3efdfb0cd39d30953b28703e519c121f1115cebfffc40369fe86c406dd1` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"hooks-codex"` | +| `summary` | required | `string` | + + + +### `{ kind: "hooks-codex", form: "recall" }` + +SHA-256: `3b4f2c9ef2c1217eac596c7b070173cb7896e2fae09e729bc7c56c801e56bb29` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "relay" }` + +SHA-256: `1fdad624334d354820dfb3a26e28d0bc9fc1b62a33f87bab63f715b3f4391bfd` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "snapshot" }` + +SHA-256: `88841202942c7683b3b7e5ea6a796047ec326b6701ac23e58cc236d85613b9fa` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"hooks-codex"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "interrupted" }` + +SHA-256: `56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23` + +Sources: [`packages/core/session/src/types.ts:221`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"interrupted"` | + + + +### `{ kind: "legacy" }` + +SHA-256: `eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c` + +Sources: [`packages/core/session/src/types.ts:196`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"legacy"` | + + + +### `{ kind: "max-tokens" }` + +SHA-256: `ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7` + +Sources: [`packages/core/session/src/types.ts:214`](../packages/core/session/src/types.ts) · [`packages/llm/llm/src/types.ts:160`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"max-tokens"` | + + + +### `{ kind: "model-selection" }` + +SHA-256: `f7283223aacdc39b0adca728c8cbd4c090a20006a6fecec74421c30e943b489c` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "catalog" }` + +SHA-256: `99135d8a3937977955eaac5f8f04f930dcd1562f8450a54a51cde9b921dd59a6` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "instructions" }` + +SHA-256: `f6605d6c57933aeaaf10911b5fbd6c61e655baa181af7192d3240f49d255b90d` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "notice" }` + +SHA-256: `a3c6f1ea38e9a61d7a9706057ba65aabe02dfe6d9dd90d4736aa62325d874531` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"model-selection"` | +| `summary` | required | `string` | + + + +### `{ kind: "model-selection", form: "recall" }` + +SHA-256: `aae343bc3d663c83f2e8b5e1c7eea5d509dc7a5361bc8bd8b5ac3bb8d3b1ed56` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "relay" }` + +SHA-256: `a15a19ef63cf5d1b711db1d249821dab0cedcd3a9ad09137b47352c93841fd20` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "snapshot" }` + +SHA-256: `52c6113cb0e53f345324bf84f01928bea5d5df57ee80bc0dd65407b8bc5a3734` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"model-selection"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "parent" }` + +SHA-256: `6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800` + +Sources: [`packages/core/session/src/types.ts:191`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"parent"` | + + + +### `{ kind: "plan-mode" }` + +SHA-256: `f4a66f654996c093aae700ea4c434ff2ee3569fea9c0e5813ccf6afdccabd163` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "catalog" }` + +SHA-256: `3b04790e08b35241ffa0d38f6d7e4f8788aa921341f6c0d7574a329397c59408` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "instructions" }` + +SHA-256: `408927267422a7b2beb6df354ff7c1406d929a5646554f48adf85eb8372f811c` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "notice" }` + +SHA-256: `baccc97ec34be6c4c78e95aa88c85c29820269479445e5b13f956cd64c5e286f` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"plan-mode"` | +| `summary` | required | `string` | + + + +### `{ kind: "plan-mode", form: "recall" }` + +SHA-256: `f6329fb30c7ea8013e8975ca5e78284fb7685cc6bd620e8aa4e9a99bc81d45eb` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "relay" }` + +SHA-256: `deaae5cd30987d4f49398e8f9d994c125907e7f928300745fb1dbf15f145d0e7` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "snapshot" }` + +SHA-256: `8c1c4f72755a78ea163523a46565316e36e9b644382eb48e6635c71a6f412dd2` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"plan-mode"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "provider" }` SHA-256: `b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812` @@ -3205,203 +6592,731 @@ Sources: [`packages/session/session-title/src/types.ts:30`](../packages/session/ | Property | Presence | Type | |---|---|---| | `kind` | required | `"provider"` | -| `model` | optional | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | +| `model` | optional | [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) | | `provider` | required | `string` | - + -### `event:step/end` +### `{ kind: "ptc-mode" }` -SHA-256: `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` +SHA-256: `dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd` + +Sources: [`packages/core/tools/src/ptc.ts:14`](../packages/core/tools/src/ptc.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:step/end.data`](#persistence-type-eventstependdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"step/end"` | +| `kind` | required | `"ptc-mode"` | - + -### `event:step/end.data` +### `{ kind: "repeat-tool-reminder" }` -SHA-256: `ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545` - -Sources: [`packages/core/session/src/types.ts:287`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts) +SHA-256: `b062078e899958f99ae464514578b8c093924dfe34bd9a835932b420ff2150b1` | Property | Presence | Type | |---|---|---| -| `step` | required | `number` | -| `turn` | required | `number` | +| `kind` | required | `"repeat-tool-reminder"` | - + -### `event:step/start` +### `{ kind: "repeat-tool-reminder", form: "catalog" }` -SHA-256: `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` +SHA-256: `d85590a5675c6e2fd8164e5792a6cceac714605b8ac228adae5ee668facb1490` | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:step/end.data`](#persistence-type-eventstependdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"step/start"` | +| `form` | required | `"catalog"` | +| `kind` | required | `"repeat-tool-reminder"` | - + -### `event:subagent/catalog` +### `{ kind: "repeat-tool-reminder", form: "instructions" }` -SHA-256: `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` +SHA-256: `6f44f32be9bcd9a8bf075c3b575b06c8ed63446386e5b0995c7b73762e68ddae` | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent`](#persistence-type-packagessubagentsubagentsrccatalogtssubagentcatalogevent) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"subagent/catalog"` | +| `form` | required | `"instructions"` | +| `kind` | required | `"repeat-tool-reminder"` | - + -### `event:subagent/catalog.data[0]` +### `{ kind: "repeat-tool-reminder", form: "notice" }` -SHA-256: `5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694` +SHA-256: `fe1a7acdeed4d0f5ab483396eaa5b3dc97263b7c10eb4da2f0028cb01728bfc9` | Property | Presence | Type | |---|---|---| -| `childCreatedAt` | required | `number` | -| `childId` | required | `string` | -| `label` | optional | `string` | -| `mode` | required | `"one-shot"` | -| `version` | required | `0` | +| `form` | required | `"notice"` | +| `kind` | required | `"repeat-tool-reminder"` | +| `summary` | required | `string` | - + -### `event:subagent/catalog.data[1]` +### `{ kind: "repeat-tool-reminder", form: "recall" }` -SHA-256: `0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd` +SHA-256: `8620189c8e33582708ece48fd2d20dc4d57912486a17bdbb9aea4c44f7018062` | Property | Presence | Type | |---|---|---| -| `childCreatedAt` | required | `number` | -| `childId` | required | `string` | -| `label` | required | `string` | -| `mode` | required | `"continuable"` | -| `version` | required | `0` | +| `form` | required | `"recall"` | +| `kind` | required | `"repeat-tool-reminder"` | - + -### `event:subagent/descriptor` +### `{ kind: "repeat-tool-reminder", form: "relay" }` -SHA-256: `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` +SHA-256: `4991dfc415c9efebc36fa6969e1798c7d2e42396cc1e6e0ac7d7c89c5c5c4aea` | Property | Presence | Type | |---|---|---| -| `data` | required | [`packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortssubagentdescriptordata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"subagent/descriptor"` | +| `form` | required | `"relay"` | +| `kind` | required | `"repeat-tool-reminder"` | - + -### `event:subagent/model-selection-policy` +### `{ kind: "repeat-tool-reminder", form: "snapshot" }` -SHA-256: `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` +SHA-256: `db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c` | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:subagent/model-selection-policy.data`](#persistence-type-eventsubagentmodel-selection-policydata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"subagent/model-selection-policy"` | +| `form` | required | `"snapshot"` | +| `kind` | required | `"repeat-tool-reminder"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | - + -### `event:subagent/model-selection-policy.data` +### `{ kind: "runtime-context" }` -SHA-256: `0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f` - -Sources: [`packages/subagent/tool-subagent/src/model-selection-state.ts:17`](../packages/subagent/tool-subagent/src/model-selection-state.ts) +SHA-256: `0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789` | Property | Presence | Type | |---|---|---| -| `allowedModels` | required | [`event:subagent/model-selection-policy.data.allowedModels`](#persistence-type-eventsubagentmodel-selection-policydataallowedmodels) | +| `kind` | required | `"runtime-context"` | - + -### `event:subagent/model-selection-policy.data.allowedModels` +### `{ kind: "runtime-context", form: "catalog" }` -SHA-256: `ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec` - -Array of [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity). - - - -### `event:system/message` - -SHA-256: `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` +SHA-256: `58015da1c1950a66daf66ae24913d6a1fc6d1d9ac441b155f8847f7f8584ba8e` | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:system/message.data`](#persistence-type-eventsystemmessagedata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | required | `number` | -| `type` | required | `"system/message"` | +| `form` | required | `"catalog"` | +| `kind` | required | `"runtime-context"` | - + -### `event:system/message.data` +### `{ kind: "runtime-context", form: "instructions" }` -SHA-256: `2074f40221b76c75fd314246db558965dc3477dfb440bcc952b1eedc9778e366` - -Sources: [`packages/core/session/src/types.ts:310`](../packages/core/session/src/types.ts) +SHA-256: `0eeb17e1df89b1ebc2902116fe7145e0d321ef0db26e6bdebc802cb8513a01c1` | Property | Presence | Type | |---|---|---| -| `message` | required | [`packages/llm/llm/src/message.ts#SystemMessage`](#persistence-type-packagesllmllmsrcmessagetssystemmessage) | -| `step` | required | `number` | -| `turn` | required | `number` | +| `form` | required | `"instructions"` | +| `kind` | required | `"runtime-context"` | - + -### `event:system/message.data.message.source` +### `{ kind: "runtime-context", form: "notice" }` -SHA-256: `23cf7e0cf3fec1283b60fa15713506169bc9c079a08e124d1cb9733baca80b40` - -One of: - -- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) -- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) -- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) -- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) -- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) -- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) -- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) - - - -### `event:team/member` - -SHA-256: `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` +SHA-256: `cda2345a9be9d139df49ccbd16dcba716f3440178bf20ff8b801fda1f5eb77dc` | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:team/member.data`](#persistence-type-eventteammemberdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"team/member"` | +| `form` | required | `"notice"` | +| `kind` | required | `"runtime-context"` | +| `summary` | required | `string` | - + -### `event:team/member.data` +### `{ kind: "runtime-context", form: "recall" }` + +SHA-256: `96bfb916a727cd4445a594df264c523fc039749a31bfed924b8cc7bb308a5bb0` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"runtime-context"` | + + + +### `{ kind: "runtime-context", form: "relay" }` + +SHA-256: `cb1c8959e1726f82f9a3d2ef2bc90bf8c451a98fd56175e956022124c770c818` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"runtime-context"` | + + + +### `{ kind: "runtime-context", form: "snapshot" }` + +SHA-256: `2aad1179f957631477b582e57cd8f538cb82618fc3fb816bde1171154235b065` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"runtime-context"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "schedule" }` + +SHA-256: `f29d63336e8266d80dd7baeab219436db86341304f6be1cd0edb36f5134c4a47` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"schedule"` | + + + +### `{ kind: "schedule", form: "catalog" }` + +SHA-256: `1e709346005826eb81809eeb76a3f713cf13ad6c5cec75146d07020ab9adc938` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"schedule"` | + + + +### `{ kind: "schedule", form: "instructions" }` + +SHA-256: `1938c8c20f1cba7c82dbedcfa4f14c3ee191cd77ed3314ee1fc676d44cadf3be` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"schedule"` | + + + +### `{ kind: "schedule", form: "notice" }` + +SHA-256: `312aee2f0c42aabbae6cc60d92d596d8453c0aeb061c5868d1755a69ef49e69a` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"schedule"` | +| `summary` | required | `string` | + + + +### `{ kind: "schedule", form: "recall" }` + +SHA-256: `a16e567c8cd2c55cf1e911aed3c200c4e1f6febb1459ff2a9e7adf159afb68cb` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"schedule"` | + + + +### `{ kind: "schedule", form: "relay" }` + +SHA-256: `5bc66269cfaf614c0ecda8ecb469f23101a7609793fc2b693ac23c4aecdb575e` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"schedule"` | + + + +### `{ kind: "schedule", form: "snapshot" }` + +SHA-256: `28936c614bd4e7e2774806edcbb3cbfd3ee643ac1cbf0bbdff43d915505a8fe3` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"schedule"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "stop" }` + +SHA-256: `1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f` + +Sources: [`packages/llm/llm/src/types.ts:158`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"stop"` | + + + +### `{ kind: "time-context" }` + +SHA-256: `b79641a9d25e756636dc0c706fdf3c4583ccb7d4920e009e6e86c0759cf4de4c` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"time-context"` | + + + +### `{ kind: "time-context", form: "catalog" }` + +SHA-256: `85fe96bf15d5c7559eec3bae4d6cf1a76fda9f5be05a29c2830cff560cab0c0d` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"time-context"` | + + + +### `{ kind: "time-context", form: "instructions" }` + +SHA-256: `f6afe41e3926f422fe849debe90819fddd739f0f59e20be9c71018b9554a7f09` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"time-context"` | + + + +### `{ kind: "time-context", form: "notice" }` + +SHA-256: `ee577a0cc18664c9daee50e9455153321155604f8f1817362f8f4a4b6fb9e1ad` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"time-context"` | +| `summary` | required | `string` | + + + +### `{ kind: "time-context", form: "recall" }` + +SHA-256: `756b5e23a5cb2c7f486f366a828f7461c88902af21125bd6810881f4ccbff6cc` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"time-context"` | + + + +### `{ kind: "time-context", form: "relay" }` + +SHA-256: `5d7a64ed6aac5551ebf998dc25e1e7b48a144769913f89702840180e61dc3995` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"time-context"` | + + + +### `{ kind: "time-context", form: "snapshot" }` + +SHA-256: `f230c0b583e23b25ee0a61dbe4c05e95c1e2ae44b27939501eb9e03696f0c278` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"time-context"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tmux-context" }` + +SHA-256: `8a046b52331959aa3394680d6acbe09b8a5447c6b61375f263445bfcef19b7f1` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "catalog" }` + +SHA-256: `7df62978a2b7de8540e714152297743e0a622209a46a5ac9513fc0fad73ca23b` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "instructions" }` + +SHA-256: `9f65c43e340bba31cdc0fc37bd93ccb68d5e9b36f47a68c207e95a8e68620a5d` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "notice" }` + +SHA-256: `b3681c026a0b98e98b103f057dfd217fbe904129c090efd668253ec9aea7fece` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"tmux-context"` | +| `summary` | required | `string` | + + + +### `{ kind: "tmux-context", form: "recall" }` + +SHA-256: `fcf81d3c58c13593bf2594e342e31734f4ab2d24938dc610875194c6079749c7` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "relay" }` + +SHA-256: `f97f47b0eb87905ed77cc27c5e4ed75ef805cb372c98905253709de1aab9b63c` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "snapshot" }` + +SHA-256: `49dab019d00e8c26f27ad2ccff7b604d69e323ae4d17e0d2a7b6b8a830b1ade2` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"tmux-context"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tool-calls" }` + +SHA-256: `287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a` + +Sources: [`packages/llm/llm/src/types.ts:159`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"tool-calls"` | + + + +### `{ kind: "tool-goal" }` + +SHA-256: `a2066bd52f61218ba15b758def2641cc6a8bd3d4a594a488ee4c65be356d7e39` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "catalog" }` + +SHA-256: `260523b412c19ad8c2bb00093b07f64245ff8ba6b2f76c5b545303772ac9704c` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "instructions" }` + +SHA-256: `6085488d223aeffdef51d7ae17655fc26ab22ee13cbed82a50e62e2b6fb5b918` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "notice" }` + +SHA-256: `8c627d7a45fa406cea879a3922105e27ed4c3c7966e264afaf11ea7a330f2dd1` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"tool-goal"` | +| `summary` | required | `string` | + + + +### `{ kind: "tool-goal", form: "recall" }` + +SHA-256: `7554565be416b0342053ee6a46256c9dab07c487349b4a5f10bab1edc151c619` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "relay" }` + +SHA-256: `8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "snapshot" }` + +SHA-256: `11638dc58a31496fb6706ced3e23e3a2db1f3b2a8845968c810827a72b5fc811` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"tool-goal"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tool-jobs" }` + +SHA-256: `24ce31aa528272e59f21cd26da9eca08968bcc97529756a749bfdab71746d9c8` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "catalog" }` + +SHA-256: `dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "instructions" }` + +SHA-256: `53cf1704ae0709c7678bcf070c83c619fc48ca1b5c173b74cfa8702f22a8e492` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "notice" }` + +SHA-256: `5bb69b88517f6214f2af4d1a6d2b771e271ad3ad695cc9c2c272069ae698c9bc` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"tool-jobs"` | +| `summary` | required | `string` | + + + +### `{ kind: "tool-jobs", form: "recall" }` + +SHA-256: `dd6cc2bb2a8f28248347021ad93565360b196a042360b4cd16b569d3a2a91f2d` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "relay" }` + +SHA-256: `ade057f4fdc387aec6426f48704a1f9359cfc6fee13f27735b07f9b215ec16ca` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "snapshot" }` + +SHA-256: `c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"tool-jobs"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tool-registry" }` + +SHA-256: `8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543` + +Sources: [`packages/core/tools/src/index.ts:34`](../packages/core/tools/src/index.ts) + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"tool-registry"` | + + + +### `{ kind: "user" }` + +SHA-256: `6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7` + +Sources: [`packages/api/session-controller/src/types.ts:385`](../packages/api/session-controller/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `clientTimeZone` | optional | `string` | +| `kind` | required | `"user"` | +| `rpcId` | required | `string` | + + + +### `{ kind: "user-approval" }` + +SHA-256: `6292bcbedaa97feaec5b48a03bb8144b581b93309d9d6c905f26da7a6a7a0a4f` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "catalog" }` + +SHA-256: `825ca23416b1ea9d81442afead5cf9229a6fa05842f042135cc3aa9710a6a2d8` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "instructions" }` + +SHA-256: `aa2bf9e82b9fdeb94a42af20031fffa30e4e23f01f4ac39757427d4c64c407f0` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "notice" }` + +SHA-256: `6ccb6bc423fb3952458abf9c1b1c3284208b7e660344b612cc55da773d61afe4` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"user-approval"` | +| `summary` | required | `string` | + + + +### `{ kind: "user-approval", form: "recall" }` + +SHA-256: `022623b9ef98ec47ec3c3bae0c51027c70d2601141c5e92e26a0d83d1b4cef06` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "relay" }` + +SHA-256: `5cdbf342b7748d152bc987b68f58e565e5bba4b227e076e2d2120d87662e45cd` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "snapshot" }` + +SHA-256: `5654685d7557ec747e74887237065e626a5bdfa426ca43f7fbb0b6fee9b0916c` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"user-approval"` | +| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "webhook", form: "notice" }` + +SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` + +Sources: [`packages/webhook/webhook/src/types.ts:74`](../packages/webhook/webhook/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `deliveryId` | required | `string` | +| `form` | required | `"notice"` | +| `kind` | required | `"webhook"` | +| `provider` | required | `string` | +| `ruleId` | required | `string` | +| `source` | required | `string` | +| `summary` | required | `string` | + + + +### `{ max_tokens, messages, model, tools }` + +SHA-256: `930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731` + +Sources: [`packages/web/web-search-deepseek/src/provider.ts:61`](../packages/web/web-search-deepseek/src/provider.ts) + +| Property | Presence | Type | +|---|---|---| +| `max_tokens` | required | `number` | +| `messages` | required | [`tuple (1 positions)`](#persistence-type-sha256-b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f) | +| `model` | required | `string` | +| `tools` | required | [`tuple (1 positions)`](#persistence-type-sha256-4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8) | + + + +### `{ member, teamId, version }` SHA-256: `b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1` @@ -3409,38 +7324,41 @@ Sources: [`packages/experimental/agent-team/src/types.ts:221`](../packages/exper | Property | Presence | Type | |---|---|---| -| `member` | required | [`packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammembersnapshot) | +| `member` | required | [`TeamMemberSnapshot`](#persistence-type-sha256-6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25) | | `teamId` | required | `string` | | `version` | required | `2` | - + -### `event:team/member.data.member.context` +### `{ message, step, turn }` -SHA-256: `50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48` +SHA-256: `6bc8e51124d0874bc89e1d0ceff381a9c3cd0fc240667d69f841ce4f60f65fe5` -One of: - -- `"fork"` -- `"fresh"` - - - -### `event:team/message/delivered` - -SHA-256: `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` +Sources: [`packages/core/session/src/types.ts:330`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:team/message/delivered.data`](#persistence-type-eventteammessagedelivereddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"team/message/delivered"` | +| `message` | required | [`SystemMessage`](#persistence-type-sha256-09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363) | +| `step` | required | `number` | +| `turn` | required | `number` | - + -### `event:team/message/delivered.data` +### `{ message, teamId, version }` + +SHA-256: `ea08ec1df0c33108fd03345b9af199cf04dea450aa045d3c683f216311403403` + +Sources: [`packages/experimental/agent-team/src/types.ts:225`](../packages/experimental/agent-team/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `message` | required | [`TeamMessageSnapshot`](#persistence-type-sha256-2eafefdc6f79a4922d68a787a09eaf4dd2b2369c3777fba4c05e800b5678ac8e) | +| `teamId` | required | `string` | +| `version` | required | `2` | + + + +### `{ messageId, targetId, teamId, version }` SHA-256: `0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1` @@ -3453,537 +7371,60 @@ Sources: [`packages/experimental/agent-team/src/types.ts:227`](../packages/exper | `teamId` | required | `string` | | `version` | required | `2` | - + -### `event:team/message/queued` +### `{ mode, source? }` -SHA-256: `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` +SHA-256: `9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e` + +Sources: [`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/sandbox/sandbox-policy/src/session-mode.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:team/message/queued.data`](#persistence-type-eventteammessagequeueddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"team/message/queued"` | +| `mode` | required | [`SandboxMode`](#persistence-type-sha256-fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd) | +| `source` | optional | `"delegation"` | - + -### `event:team/message/queued.data` +### `{ policy, source? }` -SHA-256: `0c3f4d2248d9bc9700e2d7253fa71aa9935f5c39af6f11de5727f08cccaf8383` +SHA-256: `11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912` -Sources: [`packages/experimental/agent-team/src/types.ts:225`](../packages/experimental/agent-team/src/types.ts) +Sources: [`packages/interaction/user-approval/src/index.ts:40`](../packages/interaction/user-approval/src/index.ts) | Property | Presence | Type | |---|---|---| -| `message` | required | [`packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesnapshot) | -| `teamId` | required | `string` | -| `version` | required | `2` | +| `policy` | required | [`ApprovalPolicy`](#persistence-type-sha256-05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf) | +| `source` | optional | `"delegation"` | - + -### `event:team/task` +### `{ preset }` -SHA-256: `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` +SHA-256: `8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad` + +Sources: [`packages/interaction/permission-presets/src/index.ts:57`](../packages/interaction/permission-presets/src/index.ts) | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:team/task.data`](#persistence-type-eventteamtaskdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"team/task"` | +| `preset` | required | `string` | - + -### `event:team/task.data` +### `{ reason, turn }` -SHA-256: `a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c` +SHA-256: `e481c46af3813e0010558e93f578b2986acd658404cec2d1679e3ac2a6c48654` -Sources: [`packages/experimental/agent-team/src/types.ts:223`](../packages/experimental/agent-team/src/types.ts) +Sources: [`packages/core/session/src/types.ts:297`](../packages/core/session/src/types.ts) | Property | Presence | Type | |---|---|---| -| `task` | required | [`packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtasksnapshot) | -| `teamId` | required | `string` | -| `version` | required | `2` | - - - -### `event:todo/write` - -SHA-256: `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:todo/write.data`](#persistence-type-eventtodowritedata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"todo/write"` | - - - -### `event:todo/write.data` - -SHA-256: `79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99` - -Sources: [`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `todos` | required | [`event:todo/write.data.todos`](#persistence-type-eventtodowritedatatodos) | - - - -### `event:todo/write.data.todos` - -SHA-256: `4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea` - -Array of [`packages/todo/tool-todo/src/types.ts#TodoItem`](#persistence-type-packagestodotool-todosrctypeststodoitem). - - - -### `event:todo/write.data.todos[0].status` - -SHA-256: `fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4` - -One of: - -- `"completed"` -- `"in_progress"` -- `"pending"` - - - -### `event:tool-workflow/agent-end` - -SHA-256: `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentenddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool-workflow/agent-end"` | - - - -### `event:tool-workflow/agent-start` - -SHA-256: `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentstartdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool-workflow/agent-start"` | - - - -### `event:tool-workflow/run-end` - -SHA-256: `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunenddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool-workflow/run-end"` | - - - -### `event:tool-workflow/run-start` - -SHA-256: `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunstartdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool-workflow/run-start"` | - - - -### `event:tool/call` - -SHA-256: `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:tool/call.data`](#persistence-type-eventtoolcalldata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool/call"` | - - - -### `event:tool/call.data` - -SHA-256: `e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1` - -Sources: [`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `arguments` | required | `string` | -| `callId` | required | `string` | -| `name` | required | `string` | -| `step` | required | `number` | +| `reason` | required | [`TurnEndReason`](#persistence-type-sha256-f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402) | | `turn` | required | `number` | - + -### `event:tool/ptc-dispatch` - -SHA-256: `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/core/tools/src/types.ts#PtcDispatchEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatcheventdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool/ptc-dispatch"` | - - - -### `event:tool/ptc-dispatch-start` - -SHA-256: `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/core/tools/src/types.ts#PtcDispatchStartEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatchstarteventdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"tool/ptc-dispatch-start"` | - - - -### `event:tool/ptc-dispatch.data.error` - -SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735` - -Sources: [`packages/core/session/src/types.ts:363`](../packages/core/session/src/types.ts) · [`packages/core/tools/src/types.ts:24`](../packages/core/tools/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `code` | required | `string` | -| `name` | required | `string` | -| `reason` | optional | `string` | - - - -### `event:tool/result` - -SHA-256: `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:tool/result.data`](#persistence-type-eventtoolresultdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | required | `number` | -| `type` | required | `"tool/result"` | - - - -### `event:tool/result.data` - -SHA-256: `356aad27134a0e31af67c994ff8b9e4b91acfb6c4917b3bc1f7a62bbf82794d5` - -Sources: [`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `error` | optional | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | -| `message` | required | [`packages/llm/llm/src/message.ts#ToolResultMessage`](#persistence-type-packagesllmllmsrcmessagetstoolresultmessage) | -| `meta` | optional | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | -| `step` | required | `number` | -| `turn` | required | `number` | - - - -### `event:tool/result.data.message.content` - -SHA-256: `8d6a011f3ef7096a4a922ef420458419ff6b20e1eaeece5d331db7585d2f08d6` - -| Position | Presence | Type | -|---|---|---| -| 0 | required | [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) | - - - -### `event:tool/result.data.meta` - -SHA-256: `c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6` - -Sources: [`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) - -One of: - -- [`event:tool/result.data.meta[5]`](#persistence-type-eventtoolresultdatameta5) -- [`event:tool/result.data.meta[5][0][6]`](#persistence-type-eventtoolresultdatameta506) -- `string` -- `boolean` -- `null` -- `number` - - - -### `event:tool/result.data.meta[5]` - -SHA-256: `72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227` - -Array of [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta). - - - -### `event:tool/result.data.meta[5][0][6]` - -SHA-256: `529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05` - -Sources: [`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| [`string`] | index signature | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | - - - -### `event:turn/end` - -SHA-256: `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:turn/end.data`](#persistence-type-eventturnenddata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"turn/end"` | - - - -### `event:turn/end.data` - -SHA-256: `d3e447062a2847dad847dad5168a9508d92c484363dfc76fd82605aa7bd46285` - -Sources: [`packages/core/session/src/types.ts:285`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `reason` | required | [`packages/core/session/src/types.ts#TurnEndReason`](#persistence-type-packagescoresessionsrctypeststurnendreason) | -| `turn` | required | `number` | - - - -### `event:turn/end.data.reason[0]` - -SHA-256: `b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0` - -Sources: [`packages/core/session/src/types.ts:201`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"completed"` | - - - -### `event:turn/end.data.reason[1]` - -SHA-256: `0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3` - -Sources: [`packages/core/session/src/types.ts:203`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"aborted"` | -| `reason` | required | [`packages/core/session/src/types.ts#TurnEndCancelCause`](#persistence-type-packagescoresessionsrctypeststurnendcancelcause) | - - - -### `event:turn/end.data.reason[1].reason[1]` - -SHA-256: `6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800` - -Sources: [`packages/core/session/src/types.ts:190`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"parent"` | - - - -### `event:turn/end.data.reason[1].reason[2]` - -SHA-256: `6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d` - -Sources: [`packages/core/session/src/types.ts:191`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"hook"` | -| `reason` | required | `string` | - - - -### `event:turn/end.data.reason[1].reason[3]` - -SHA-256: `4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db` - -Sources: [`packages/core/session/src/types.ts:192`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"disposed"` | - - - -### `event:turn/end.data.reason[1].reason[4]` - -SHA-256: `eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c` - -Sources: [`packages/core/session/src/types.ts:195`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"legacy"` | - - - -### `event:turn/end.data.reason[2]` - -SHA-256: `023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4` - -Sources: [`packages/core/session/src/types.ts:205`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"blocked"` | - - - -### `event:turn/end.data.reason[3]` - -SHA-256: `79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985` - -Sources: [`packages/core/session/src/types.ts:211`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `error` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | -| `kind` | required | `"error"` | - - - -### `event:turn/end.data.reason[5]` - -SHA-256: `56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23` - -Sources: [`packages/core/session/src/types.ts:220`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"interrupted"` | - - - -### `event:turn/start` - -SHA-256: `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`event:turn/start.data`](#persistence-type-eventturnstartdata) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"turn/start"` | - - - -### `event:turn/start.data` - -SHA-256: `f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d` - -Sources: [`packages/core/session/src/types.ts:276`](../packages/core/session/src/types.ts) · [`packages/deliverables/workspace-changes/src/types.ts:106`](../packages/deliverables/workspace-changes/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `turn` | required | `number` | - - - -### `event:user/message` - -SHA-256: `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | required | `number` | -| `type` | required | `"user/message"` | - - - -### `event:web/deepseek-search-llm-request` - -SHA-256: `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` - -| Property | Presence | Type | -|---|---|---| -| `data` | required | [`packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest`](#persistence-type-packageswebweb-search-deepseeksrcprovidertsdeepseeksearchllmrequest) | -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `"web/deepseek-search-llm-request"` | - - - -### `event:web/deepseek-search-llm-request.data.body` - -SHA-256: `930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731` - -Sources: [`packages/web/web-search-deepseek/src/provider.ts:61`](../packages/web/web-search-deepseek/src/provider.ts) - -| Property | Presence | Type | -|---|---|---| -| `max_tokens` | required | `number` | -| `messages` | required | [`event:web/deepseek-search-llm-request.data.body.messages`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages) | -| `model` | required | `string` | -| `tools` | required | [`event:web/deepseek-search-llm-request.data.body.tools`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools) | - - - -### `event:web/deepseek-search-llm-request.data.body.messages` - -SHA-256: `b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f` - -| Position | Presence | Type | -|---|---|---| -| 0 | required | [`event:web/deepseek-search-llm-request.data.body.messages[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0) | - - - -### `event:web/deepseek-search-llm-request.data.body.messages[0]` +### `{ role: "user" }` SHA-256: `9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5` @@ -3991,45 +7432,1217 @@ Sources: [`packages/web/web-search-deepseek/src/provider.ts:64`](../packages/web | Property | Presence | Type | |---|---|---| -| `content` | required | [`event:web/deepseek-search-llm-request.data.body.messages[0].content`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content) | +| `content` | required | [`tuple (1 positions)`](#persistence-type-sha256-8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9) | | `role` | required | `"user"` | - + -### `event:web/deepseek-search-llm-request.data.body.messages[0].content` +### `{ sessionFormatVersion?, sessionId, throughSeq }` -SHA-256: `8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9` +SHA-256: `8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52` -| Position | Presence | Type | -|---|---|---| -| 0 | required | [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) | - - - -### `event:web/deepseek-search-llm-request.data.body.messages[0].content[0]` - -SHA-256: `4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c` - -Sources: [`packages/llm/llm/src/types.ts:61`](../packages/llm/llm/src/types.ts) · [`packages/web/web-search-deepseek/src/provider.ts:66`](../packages/web/web-search-deepseek/src/provider.ts) +Sources: [`packages/session/session-log-deepseek/src/types.ts:81`](../packages/session/session-log-deepseek/src/types.ts) | Property | Presence | Type | |---|---|---| -| `text` | required | `string` | -| `type` | required | `"text"` | +| `sessionFormatVersion` | optional | `number` | +| `sessionId` | required | `string` | +| `throughSeq` | required | `number` | - + -### `event:web/deepseek-search-llm-request.data.body.tools` +### `{ shadowedRange, shadowedSeqs, shadowedTokenCount }` -SHA-256: `4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8` +SHA-256: `5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438` -| Position | Presence | Type | +Sources: [`packages/compaction/compaction/src/types.ts:82`](../packages/compaction/compaction/src/types.ts) + +| Property | Presence | Type | |---|---|---| -| 0 | required | [`event:web/deepseek-search-llm-request.data.body.tools[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools0) | +| `shadowedRange` | required | [`{ end, start }`](#persistence-type-sha256-9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2) | +| `shadowedSeqs` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `shadowedTokenCount` | required | `number` | - + -### `event:web/deepseek-search-llm-request.data.body.tools[0]` +### `{ step, stream, turn }` + +SHA-256: `54f9276a1617d7c12594722c89cfe864bcbe4517e9a6f9c98bab14f199a135e0` + +Sources: [`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `step` | required | `number` | +| `stream` | required | [`AssistantStreamRecord[]`](#persistence-type-sha256-84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7) | +| `turn` | required | `number` | + + + +### `{ step, turn }` + +SHA-256: `ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545` + +Sources: [`packages/core/session/src/types.ts:299`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:301`](../packages/core/session/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `step` | required | `number` | +| `turn` | required | `number` | + + + +### `{ targets }` + +SHA-256: `477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028` + +Sources: [`packages/compaction/compaction-image-offload/src/projection.ts:25`](../packages/compaction/compaction-image-offload/src/projection.ts) + +| Property | Presence | Type | +|---|---|---| +| `targets` | required | [`ImageOffloadTarget[]`](#persistence-type-sha256-9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb) | + + + +### `{ task, teamId, version }` + +SHA-256: `a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c` + +Sources: [`packages/experimental/agent-team/src/types.ts:223`](../packages/experimental/agent-team/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `task` | required | [`TeamTaskSnapshot`](#persistence-type-sha256-51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357) | +| `teamId` | required | `string` | +| `version` | required | `2` | + + + +### `{ todos }` + +SHA-256: `79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99` + +Sources: [`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `todos` | required | [`TodoItem[]`](#persistence-type-sha256-4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea) | + + + +### `{ turn }` + +SHA-256: `f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d` + +Sources: [`packages/core/session/src/types.ts:288`](../packages/core/session/src/types.ts) · [`packages/deliverables/workspace-changes/src/types.ts:106`](../packages/deliverables/workspace-changes/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `turn` | required | `number` | + + + + + +### `{ type: "agent-preset/selected" }` + +SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ agentPreset }`](#persistence-type-sha256-6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"agent-preset/selected"` | + + + + + +### `{ type: "agent/inbox/spliced" }` + +SHA-256: `1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ inserted, outcome?, removedCount?, start, … }`](#persistence-type-sha256-dc4bd7ac827f4b1f9236f9a157a4b4cc171a0588064a611e43edd95f62c68130) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"agent/inbox/spliced"` | + + + + + +### `{ type: "approval/asked" }` + +SHA-256: `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ callId?, id, reason?, toolName }`](#persistence-type-sha256-45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"approval/asked"` | + + + + + +### `{ type: "approval/decided" }` + +SHA-256: `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ id, outcome }`](#persistence-type-sha256-93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"approval/decided"` | + + + + + +### `{ type: "approval/policy" }` + +SHA-256: `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ policy, source? }`](#persistence-type-sha256-11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"approval/policy"` | + + + + + +### `{ type: "assistant/attempt" }` + +SHA-256: `15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ step, stream, turn }`](#persistence-type-sha256-54f9276a1617d7c12594722c89cfe864bcbe4517e9a6f9c98bab14f199a135e0) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"assistant/attempt"` | + + + + + +### `{ type: "assistant/message" }` + +SHA-256: `1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ interrupted?, message, step, stream, … }`](#persistence-type-sha256-1ccb56061942f5ccb0d30c9e4f2883b9d115ff906560029de637b61d3cde896d) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `"assistant/message"` | + + + +### `{ type: "block-end" }` + +SHA-256: `d4b739491689cc6bb13d07ffac1a32239875abda364c0d5edd8f74faf5e9c00d` + +Sources: [`packages/llm/llm/src/types.ts:445`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `block` | required | [`ContentBlock`](#persistence-type-sha256-8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5) | +| `index` | required | `number` | +| `type` | required | `"block-end"` | + + + +### `{ type: "block-start" }` + +SHA-256: `3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90` + +Sources: [`packages/llm/llm/src/types.ts:441`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `blockType` | required | [`ContentBlockType`](#persistence-type-sha256-7d65acf0a3a43a8f445ce5d3320b42eca492739fc931b2a7516bfb8368dc2c68) | +| `index` | required | `number` | +| `type` | required | `"block-start"` | + + + +### `{ type: "chunk" }` + +SHA-256: `487b65c37bfedb8b72088c4107a0a90a6249701f6b26745f6d98f9b8a22b07c7` + +Sources: [`packages/llm/llm/src/assistant-stream.ts:44`](../packages/llm/llm/src/assistant-stream.ts) + +| Property | Presence | Type | +|---|---|---| +| `chunk` | required | [`StreamChunk`](#persistence-type-sha256-47e9095591ae36e7c39ee62553097772f2bfa16304536a72dbbc3f691f605180) | +| `time` | required | `number` | +| `type` | required | `"chunk"` | + + + + + +### `{ type: "command/done" }` + +SHA-256: `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ commandId, kind, sourceEventSeq?, text? }`](#persistence-type-sha256-5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"command/done"` | + + + + + +### `{ type: "command/run" }` + +SHA-256: `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ args?, commandId, name, source }`](#persistence-type-sha256-a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"command/run"` | + + + + + +### `{ type: "compaction/end" }` + +SHA-256: `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ compactionId, error?, sourceCommandId?, turn }`](#persistence-type-sha256-ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/end"` | + + + + + +### `{ type: "compaction/prune" }` + +SHA-256: `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ shadowedRange, shadowedSeqs, shadowedTokenCount }`](#persistence-type-sha256-5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/prune"` | + + + + + +### `{ type: "compaction/start" }` + +SHA-256: `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ compactionId, sourceCommandId?, turn }`](#persistence-type-sha256-3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/start"` | + + + + + +### `{ type: "compaction/summary" }` + +SHA-256: `e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`union (2 variants)`](#persistence-type-sha256-9947aa5938fe19a895298da412917acbf9ffb5093a73ab8baa257e6ae9e63a07) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/summary"` | + + + + + +### `{ type: "deliverables/presented" }` + +SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ callId, files, turn }`](#persistence-type-sha256-1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"deliverables/presented"` | + + + + + +### `{ type: "developer/message" }` + +SHA-256: `eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ headerSeq?, message, step, turn }`](#persistence-type-sha256-51c78ccc9023ce6642d07fb9a10cbf942ff7e313d5b304ddc77218df71da708f) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `"developer/message"` | + + + + + +### `{ type: "feedback/message-delete" }` + +SHA-256: `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`MessageFeedbackDelete`](#persistence-type-sha256-7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"feedback/message-delete"` | + + + + + +### `{ type: "feedback/message-put" }` + +SHA-256: `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`MessageFeedbackPut`](#persistence-type-sha256-aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"feedback/message-put"` | + + + + + +### `{ type: "feedback/record" }` + +SHA-256: `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`FeedbackRecord`](#persistence-type-sha256-7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"feedback/record"` | + + + +### `{ type: "finish" }` + +SHA-256: `a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1` + +Sources: [`packages/llm/llm/src/types.ts:447`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `reason` | required | [`FinishReason`](#persistence-type-sha256-5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80) | +| `replayState` | optional | [`ReplayEnvelope`](#persistence-type-sha256-0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555) | +| `type` | required | `"finish"` | + + + + + +### `{ type: "goal/change" }` + +SHA-256: `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`GoalChangeMeta`](#persistence-type-sha256-7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"goal/change"` | + + + + + +### `{ type: "hook/invoked" }` + +SHA-256: `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ dialect, handlerId, matcher?, point, … }`](#persistence-type-sha256-119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"hook/invoked"` | + + + + + +### `{ type: "hook/result" }` + +SHA-256: `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ decision, durationMs, exitCode?, handlerId, … }`](#persistence-type-sha256-8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"hook/result"` | + + + + + +### `{ type: "image/offload" }` + +SHA-256: `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ targets }`](#persistence-type-sha256-477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"image/offload"` | + + + + + +### `{ type: "llm/retry" }` + +SHA-256: `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`LlmRetryEventData`](#persistence-type-sha256-c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"llm/retry"` | + + + + + +### `{ type: "llm/retry-started" }` + +SHA-256: `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`LlmRetryStartedEventData`](#persistence-type-sha256-6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"llm/retry-started"` | + + + + + +### `{ type: "model/selection" }` + +SHA-256: `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`ModelSelection`](#persistence-type-sha256-f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"model/selection"` | + + + + + +### `{ type: "permission/preset" }` + +SHA-256: `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ preset }`](#persistence-type-sha256-8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"permission/preset"` | + + + + + +### `{ type: "plan/mode" }` + +SHA-256: `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ active }`](#persistence-type-sha256-20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"plan/mode"` | + + + +### `{ type: "reasoning-chunks" }` + +SHA-256: `71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd` + +Sources: [`packages/llm/llm/src/assistant-stream.ts:28`](../packages/llm/llm/src/assistant-stream.ts) + +| Property | Presence | Type | +|---|---|---| +| `dt` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `index` | required | `number` | +| `texts` | required | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `time0` | required | `number` | +| `type` | required | `"reasoning-chunks"` | + + + +### `{ type: "reasoning-delta" }` + +SHA-256: `2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095` + +Sources: [`packages/llm/llm/src/types.ts:443`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `index` | required | `number` | +| `text` | required | `string` | +| `type` | required | `"reasoning-delta"` | + + + + + +### `{ type: "request/context" }` + +SHA-256: `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`RequestContext`](#persistence-type-sha256-b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"request/context"` | + + + + + +### `{ type: "request/header" }` + +SHA-256: `4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ header, reason, startsSeries? }`](#persistence-type-sha256-ad0c38a0adb82a94c925456df41586d9b5f9202fca18593eae2213d4445b4585) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"request/header"` | + + + + + +### `{ type: "sandbox/mode" }` + +SHA-256: `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ mode, source? }`](#persistence-type-sha256-9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"sandbox/mode"` | + + + + + +### `{ type: "schedule/change" }` + +SHA-256: `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`ScheduleChange`](#persistence-type-sha256-e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"schedule/change"` | + + + + + +### `{ type: "session-log-deepseek/delivery-accepted" }` + +SHA-256: `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ sessionFormatVersion?, sessionId, throughSeq }`](#persistence-type-sha256-8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session-log-deepseek/delivery-accepted"` | + + + + + +### `{ type: "session/end-seed" }` + +SHA-256: `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ inherited? }`](#persistence-type-sha256-17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session/end-seed"` | + + + + + +### `{ type: "session/title" }` + +SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`SessionTitleEventData`](#persistence-type-sha256-b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session/title"` | + + + + + +### `{ type: "session/title-llm-request" }` + +SHA-256: `fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`SessionTitleLlmRequestEventData`](#persistence-type-sha256-9bc85364d1f37d9c837db6a3bdd3d1d007d923cdc7401a3322be9f12fdc225fd) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session/title-llm-request"` | + + + + + +### `{ type: "step/end" }` + +SHA-256: `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ step, turn }`](#persistence-type-sha256-ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"step/end"` | + + + + + +### `{ type: "step/start" }` + +SHA-256: `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ step, turn }`](#persistence-type-sha256-ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"step/start"` | + + + + + +### `{ type: "subagent/catalog" }` + +SHA-256: `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`SubagentCatalogEvent`](#persistence-type-sha256-3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"subagent/catalog"` | + + + + + +### `{ type: "subagent/descriptor" }` + +SHA-256: `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`SubagentDescriptorData`](#persistence-type-sha256-86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"subagent/descriptor"` | + + + + + +### `{ type: "subagent/model-selection-policy" }` + +SHA-256: `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ allowedModels }`](#persistence-type-sha256-0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"subagent/model-selection-policy"` | + + + + + +### `{ type: "system/message" }` + +SHA-256: `69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ message, step, turn }`](#persistence-type-sha256-6bc8e51124d0874bc89e1d0ceff381a9c3cd0fc240667d69f841ce4f60f65fe5) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `"system/message"` | + + + + + +### `{ type: "team/member" }` + +SHA-256: `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ member, teamId, version }`](#persistence-type-sha256-b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/member"` | + + + + + +### `{ type: "team/message/delivered" }` + +SHA-256: `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ messageId, targetId, teamId, version }`](#persistence-type-sha256-0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/message/delivered"` | + + + + + +### `{ type: "team/message/queued" }` + +SHA-256: `21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ message, teamId, version }`](#persistence-type-sha256-ea08ec1df0c33108fd03345b9af199cf04dea450aa045d3c683f216311403403) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/message/queued"` | + + + + + +### `{ type: "team/task" }` + +SHA-256: `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ task, teamId, version }`](#persistence-type-sha256-a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/task"` | + + + +### `{ type: "text-chunks" }` + +SHA-256: `e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33` + +Sources: [`packages/llm/llm/src/assistant-stream.ts:21`](../packages/llm/llm/src/assistant-stream.ts) + +| Property | Presence | Type | +|---|---|---| +| `dt` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `index` | required | `number` | +| `texts` | required | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `time0` | required | `number` | +| `type` | required | `"text-chunks"` | + + + +### `{ type: "text-delta" }` + +SHA-256: `95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65` + +Sources: [`packages/llm/llm/src/types.ts:442`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `index` | required | `number` | +| `text` | required | `string` | +| `type` | required | `"text-delta"` | + + + + + +### `{ type: "todo/write" }` + +SHA-256: `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ todos }`](#persistence-type-sha256-79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"todo/write"` | + + + +### `{ type: "tool-call-chunks" }` + +SHA-256: `3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6` + +Sources: [`packages/llm/llm/src/assistant-stream.ts:35`](../packages/llm/llm/src/assistant-stream.ts) + +| Property | Presence | Type | +|---|---|---| +| `args` | required | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `dt` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `id` | required | `string` | +| `index` | required | `number` | +| `name` | optional | `string` | +| `time0` | required | `number` | +| `type` | required | `"tool-call-chunks"` | + + + +### `{ type: "tool-call-delta" }` + +SHA-256: `88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a` + +Sources: [`packages/llm/llm/src/types.ts:444`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `argumentsDelta` | required | `string` | +| `id` | required | `string` | +| `index` | required | `number` | +| `name` | optional | `string` | +| `type` | required | `"tool-call-delta"` | + + + + + +### `{ type: "tool-workflow/agent-end" }` + +SHA-256: `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`ToolWorkflowAgentEndData`](#persistence-type-sha256-c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/agent-end"` | + + + + + +### `{ type: "tool-workflow/agent-start" }` + +SHA-256: `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`ToolWorkflowAgentStartData`](#persistence-type-sha256-9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/agent-start"` | + + + + + +### `{ type: "tool-workflow/run-end" }` + +SHA-256: `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`ToolWorkflowRunEndData`](#persistence-type-sha256-7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/run-end"` | + + + + + +### `{ type: "tool-workflow/run-start" }` + +SHA-256: `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`ToolWorkflowRunStartData`](#persistence-type-sha256-a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/run-start"` | + + + + + +### `{ type: "tool/call" }` + +SHA-256: `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ arguments, callId, name, step, … }`](#persistence-type-sha256-e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool/call"` | + + + + + +### `{ type: "tool/ptc-dispatch" }` + +SHA-256: `100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`PtcDispatchEventData`](#persistence-type-sha256-0ee52de154f8955c7abc82cffebc57452dcc8c44dccbdb6ad16c71a11305ead8) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool/ptc-dispatch"` | + + + + + +### `{ type: "tool/ptc-dispatch-start" }` + +SHA-256: `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`PtcDispatchStartEventData`](#persistence-type-sha256-2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool/ptc-dispatch-start"` | + + + + + +### `{ type: "tool/result" }` + +SHA-256: `7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ error?, message, meta?, step, … }`](#persistence-type-sha256-5302e763151277614b97e77f00e3b326694c6c1247b916a20503c344dc970777) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `"tool/result"` | + + + + + +### `{ type: "turn/end" }` + +SHA-256: `0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ reason, turn }`](#persistence-type-sha256-e481c46af3813e0010558e93f578b2986acd658404cec2d1679e3ac2a6c48654) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"turn/end"` | + + + + + +### `{ type: "turn/start" }` + +SHA-256: `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`{ turn }`](#persistence-type-sha256-f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"turn/start"` | + + + +### `{ type: "usage" }` + +SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515` + +Sources: [`packages/llm/llm/src/types.ts:446`](../packages/llm/llm/src/types.ts) + +| Property | Presence | Type | +|---|---|---| +| `type` | required | `"usage"` | +| `usage` | required | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | + + + + + +### `{ type: "user/message" }` + +SHA-256: `3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`UserMessage`](#persistence-type-sha256-64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | required | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | required | `number` | +| `type` | required | `"user/message"` | + + + + + +### `{ type: "web/deepseek-search-llm-request" }` + +SHA-256: `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`DeepSeekSearchLlmRequest`](#persistence-type-sha256-2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"web/deepseek-search-llm-request"` | + + + +### `{ type: "web_search_20250305" }` SHA-256: `2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3` @@ -4041,2670 +8654,40 @@ Sources: [`packages/web/web-search-deepseek/src/provider.ts:71`](../packages/web | `name` | required | `"web_search"` | | `type` | required | `"web_search_20250305"` | + + -### `event:workspace/changes` +### `{ type: "workspace/changes" }` SHA-256: `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | Property | Presence | Type | |---|---|---| -| `data` | required | [`event:turn/start.data`](#persistence-type-eventturnstartdata) | +| `data` | required | [`{ turn }`](#persistence-type-sha256-f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d) | | `ignorable` | optional | `true` | | `seq` | required | `number` | | `time` | required | `number` | | `type` | required | `"workspace/changes"` | - + -### `"every"` +### `{}` -SHA-256: `e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87` - -`"every"` - - - -### `"failed"` - -SHA-256: `b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420` - -`"failed"` - - - -### `"fallback"` - -SHA-256: `d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c` - -`"fallback"` - - - -### `false` - -SHA-256: `0c4205180f75b9ee1e0d878bd9a9851628b5dc18448486389d9c5fdc3f1ccda3` - -`false` - - - -### `"feedback/message-delete"` - -SHA-256: `44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e` - -`"feedback/message-delete"` - - - -### `"feedback/message-put"` - -SHA-256: `6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8` - -`"feedback/message-put"` - - - -### `"feedback/record"` - -SHA-256: `c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954` - -`"feedback/record"` - - - -### `"file"` - -SHA-256: `277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9` - -`"file"` - - - -### `"finish"` - -SHA-256: `bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd` - -`"finish"` - - - -### `"fork"` - -SHA-256: `2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863` - -`"fork"` - - - -### `"fresh"` - -SHA-256: `dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d` - -`"fresh"` - - - -### `"goal"` - -SHA-256: `b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602` - -`"goal"` - - - -### `"goal/change"` - -SHA-256: `237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163` - -`"goal/change"` - - - -### `"hook"` - -SHA-256: `dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc` - -`"hook"` - - - -### `"hook/invoked"` - -SHA-256: `b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611` - -`"hook/invoked"` - - - -### `"hook/result"` - -SHA-256: `a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2` - -`"hook/result"` - - - -### `"image"` - -SHA-256: `fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0` - -`"image"` - - - -### `"image/gif"` - -SHA-256: `de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048` - -`"image/gif"` - - - -### `"image/jpeg"` - -SHA-256: `3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004` - -`"image/jpeg"` - - - -### `"image/offload"` - -SHA-256: `9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49` - -`"image/offload"` - - - -### `"image/png"` - -SHA-256: `58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0` - -`"image/png"` - - - -### `"image/webp"` - -SHA-256: `ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8` - -`"image/webp"` - - - -### `"in-history"` - -SHA-256: `f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5` - -Sources: [`packages/llm/llm/src/types.ts:383`](../packages/llm/llm/src/types.ts) - -`"in-history"` - - - -### `"in_progress"` - -SHA-256: `94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378` - -`"in_progress"` - - - -### `"initial"` - -SHA-256: `e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c` - -`"initial"` - - - -### `"instruction-following"` - -SHA-256: `e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486` - -`"instruction-following"` - - - -### `"instructions"` - -SHA-256: `fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5` - -`"instructions"` - - - -### `"interrupted"` - -SHA-256: `69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199` - -`"interrupted"` - - - -### `"legacy"` - -SHA-256: `ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc` - -`"legacy"` - - - -### `"llm/retry"` - -SHA-256: `611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d` - -`"llm/retry"` - - - -### `"llm/retry-started"` - -SHA-256: `4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964` - -`"llm/retry-started"` - - - -### `"max-tokens"` - -SHA-256: `68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe` - -`"max-tokens"` - - - -### `"model"` - -SHA-256: `2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e` - -`"model"` - - - -### `"model/selection"` - -SHA-256: `1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2` - -`"model/selection"` - - - -### `"negative"` - -SHA-256: `b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5` - -`"negative"` - - - -### `"never"` - -SHA-256: `1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b` - -`"never"` - - - -### `"next-step"` - -SHA-256: `3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693` - -`"next-step"` - - - -### `"next-turn"` - -SHA-256: `62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd` - -`"next-turn"` - - - -### `"normal"` - -SHA-256: `3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79` - -`"normal"` - - - -### `"notice"` - -SHA-256: `e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367` - -`"notice"` - - - -### `null` - -SHA-256: `938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615` - -`null` - - - -### `number` - -SHA-256: `0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7` - -Sources: [`packages/core/session/src/types.ts:31`](../packages/core/session/src/types.ts) - -`number` - - - -### `"one-shot"` - -SHA-256: `d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2` - -`"one-shot"` - - - -### `"other"` - -SHA-256: `9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4` - -`"other"` - - - -### `packages/api/session-controller/src/types.ts#ModelSelection` - -SHA-256: `f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b` - -Sources: [`packages/api/session-controller/src/types.ts:86`](../packages/api/session-controller/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `model` | required | `string` | -| `provider` | required | `string` | -| `reasoningEffort` | optional | `string` | - - - -### `packages/attachment/attachment/src/types.ts#FileAttachmentRef` - -SHA-256: `f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6` - -Sources: [`packages/attachment/attachment/src/types.ts:39`](../packages/attachment/attachment/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `attachmentId` | required | `string` | -| `bytes` | required | `number` | -| `name` | required | `string` | - - - -### `packages/attachment/attachment/src/types.ts#ImageAttachmentRef` - -SHA-256: `b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35` - -Sources: [`packages/attachment/attachment/src/types.ts:11`](../packages/attachment/attachment/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `attachmentId` | required | `string` | -| `bytes` | required | `number` | -| `height` | required | `number` | -| `mediaType` | required | [`packages/attachment/attachment/src/types.ts#ImageMediaType`](#persistence-type-packagesattachmentattachmentsrctypestsimagemediatype) | -| `name` | optional | `string` | -| `originalDimensions` | optional | [`event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions`](#persistence-type-eventagentinboxspliceddatainserted0content02attachmentoriginaldimensions) | -| `width` | required | `number` | - - - -### `packages/attachment/attachment/src/types.ts#ImageMediaType` - -SHA-256: `2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716` - -Sources: [`packages/attachment/attachment/src/types.ts:8`](../packages/attachment/attachment/src/types.ts) - -One of: - -- `"image/gif"` -- `"image/jpeg"` -- `"image/png"` -- `"image/webp"` - - - -### `packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget` - -SHA-256: `1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f` - -Sources: [`packages/compaction/compaction-image-offload/src/projection.ts:9`](../packages/compaction/compaction-image-offload/src/projection.ts) - -| Property | Presence | Type | -|---|---|---| -| `imageIndexes` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `seq` | required | `number` | - - - -### `packages/context/agent-instructions/src/render.ts#AgentInstructionChange` - -SHA-256: `83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239` - -Sources: [`packages/context/agent-instructions/src/render.ts:47`](../packages/context/agent-instructions/src/render.ts) - -| Property | Presence | Type | -|---|---|---| -| `action` | required | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action`](#persistence-type-eventagentinboxspliceddatainserted0source16changes0action) | -| `digest` | optional | `string` | -| `path` | required | `string` | -| `scope` | required | `string` | - - - -### `packages/context/agent-instructions/src/state.ts#AgentInstructionSource` - -SHA-256: `6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590` - -Sources: [`packages/context/agent-instructions/src/state.ts:37`](../packages/context/agent-instructions/src/state.ts) - -| Property | Presence | Type | -|---|---|---| -| `baseline` | optional | `true` | -| `baselineIdentity` | optional | `string` | -| `changes` | required | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes`](#persistence-type-eventagentinboxspliceddatainserted0source16changes) | -| `form` | required | `"instructions"` | -| `kind` | required | `"agent-instructions"` | - - - -### `packages/context/session-reference/src/types.ts#SessionReferenceSource` - -SHA-256: `f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f` - -Sources: [`packages/context/session-reference/src/types.ts:13`](../packages/context/session-reference/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"recall"` | -| `kind` | required | `"session-reference"` | -| `references` | required | [`event:agent/inbox/spliced.data.inserted[0].source[15].references`](#persistence-type-eventagentinboxspliceddatainserted0source15references) | -| `version` | required | `1` | - - - -### `packages/core/agent/src/types.ts#InboxTarget` - -SHA-256: `96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c` - -Sources: [`packages/core/agent/src/types.ts:30`](../packages/core/agent/src/types.ts) - -One of: - -- `"next-step"` -- `"next-turn"` - - - -### `packages/core/session/src/types.ts#EpochHeader` - -SHA-256: `c55a891c7aac496de6ee64c91c1fb65728c977314013033e42c863428aada854` - -Sources: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `adapterDefaults` | optional | [`packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfigadapterdefaults) | -| `config` | required | [`packages/llm/llm/src/call-config.ts#LlmCallConfig`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfig) | -| `tools` | optional | [`event:request/header.data.header.tools`](#persistence-type-eventrequestheaderdataheadertools) | - - - -### `packages/core/session/src/types.ts#RequestContext` - -SHA-256: `b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081` - -Sources: [`packages/core/session/src/types.ts:242`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `contextWindow` | optional | `number` | -| `model` | required | `string` | -| `provider` | required | `string` | -| `systemPromptUpdate` | optional | `"in-history"` | - - - -### `packages/core/session/src/types.ts#RequestHeaderReason` - -SHA-256: `530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6` - -Sources: [`packages/core/session/src/types.ts:261`](../packages/core/session/src/types.ts) - -One of: - -- `"change"` -- `"initial"` -- `"resume"` -- `"series"` - - - -### `packages/core/session/src/types.ts#SessionHeader` - -SHA-256: `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` - -Sources: [`packages/core/session/src/types.ts:93`](../packages/core/session/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `agentPreset` | optional | `string` | -| `createdAt` | required | `number` | -| `cwd` | optional | `string` | -| `delegationDepth` | optional | `number` | -| `id` | required | `string` | -| `isSeeded` | required | `boolean` | -| `origin` | optional | `"subagent"` | -| `parentSession` | optional | `string` | -| `version` | required | `3` | - - - -### `packages/core/session/src/types.ts#SurfaceOp` - -SHA-256: `335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5` - -Sources: [`packages/core/session/src/types.ts:439`](../packages/core/session/src/types.ts) - -One of: - -- `"append"` -- [`SessionEventEnvelope[6].surfaceOp[1]`](#persistence-type-sessioneventenvelope6surfaceop1) - - - -### `packages/core/session/src/types.ts#TurnEndCancelCause` - -SHA-256: `1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0` - -Sources: [`packages/core/session/src/types.ts:195`](../packages/core/session/src/types.ts) - -One of: - -- [`event:turn/end.data.reason[1].reason[2]`](#persistence-type-eventturnenddatareason1reason2) -- [`event:turn/end.data.reason[1].reason[3]`](#persistence-type-eventturnenddatareason1reason3) -- [`event:turn/end.data.reason[1].reason[4]`](#persistence-type-eventturnenddatareason1reason4) -- [`event:turn/end.data.reason[1].reason[1]`](#persistence-type-eventturnenddatareason1reason1) -- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) - - - -### `packages/core/session/src/types.ts#TurnEndReason` - -SHA-256: `a5a8c15f08af1b0f26f40906e0797b6b0920fd01069e660becce35ab7fc48d77` - -Sources: [`packages/core/session/src/types.ts:224`](../packages/core/session/src/types.ts) - -One of: - -- [`event:turn/end.data.reason[5]`](#persistence-type-eventturnenddatareason5) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) -- [`event:turn/end.data.reason[3]`](#persistence-type-eventturnenddatareason3) -- [`event:turn/end.data.reason[1]`](#persistence-type-eventturnenddatareason1) -- [`event:turn/end.data.reason[2]`](#persistence-type-eventturnenddatareason2) -- [`event:turn/end.data.reason[0]`](#persistence-type-eventturnenddatareason0) - - - -### `packages/core/tools/src/index.ts#ToolRestriction` - -SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f` - -Sources: [`packages/core/tools/src/index.ts:682`](../packages/core/tools/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| `allow` | optional | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `deny` | optional | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | - - - -### `packages/core/tools/src/types.ts#PtcDispatchEventData` - -SHA-256: `8d2e5a3c4230e6ea6c0b5151f02241d0db02cd2551f2df1b6b9700cddcc0dca3` - -Sources: [`packages/core/tools/src/types.ts:20`](../packages/core/tools/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `arguments` | required | `unknown` (opaque) | -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `error` | optional | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | -| `isError` | required | `boolean` | -| `name` | required | `string` | -| `parentCallId` | required | `string` | -| `rootCallId` | required | `string` | -| `subCallId` | required | `string` | - - - -### `packages/core/tools/src/types.ts#PtcDispatchStartEventData` - -SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f` - -Sources: [`packages/core/tools/src/types.ts:11`](../packages/core/tools/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `arguments` | required | `unknown` (opaque) | -| `name` | required | `string` | -| `parentCallId` | required | `string` | -| `rootCallId` | required | `string` | -| `subCallId` | required | `string` | - - - -### `packages/deliverables/tool-present/src/types.ts#PresentedFile` - -SHA-256: `b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97` - -Sources: [`packages/deliverables/tool-present/src/types.ts:5`](../packages/deliverables/tool-present/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `description` | optional | `string` | -| `path` | required | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamMemberPhase` - -SHA-256: `dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd` - -Sources: [`packages/experimental/agent-team/src/types.ts:44`](../packages/experimental/agent-team/src/types.ts) - -One of: - -- `"active"` -- `"failed"` -- `"provisioning"` - - - -### `packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot` - -SHA-256: `6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25` - -Sources: [`packages/experimental/agent-team/src/types.ts:47`](../packages/experimental/agent-team/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `context` | required | [`event:team/member.data.member.context`](#persistence-type-eventteammemberdatamembercontext) | -| `description` | required | `string` | -| `error` | optional | `string` | -| `id` | required | `string` | -| `name` | required | `string` | -| `phase` | required | [`packages/experimental/agent-team/src/types.ts#TeamMemberPhase`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammemberphase) | -| `provider` | required | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot` - -SHA-256: `5b694f394d5e11609887a3ccfa82844935d49806c37e336b30be2186d649ab94` - -Sources: [`packages/experimental/agent-team/src/types.ts:106`](../packages/experimental/agent-team/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | required | `string` | -| `senderId` | required | `string` | -| `senderName` | required | `string` | -| `targetId` | required | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamMessageSource` - -SHA-256: `2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0` - -Sources: [`packages/experimental/agent-team/src/types.ts:115`](../packages/experimental/agent-team/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"team-message"` | -| `messageId` | required | `string` | -| `senderId` | required | `string` | -| `senderName` | required | `string` | -| `teamId` | required | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot` - -SHA-256: `51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357` - -Sources: [`packages/experimental/agent-team/src/types.ts:74`](../packages/experimental/agent-team/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `blockedBy` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `description` | required | `string` | -| `id` | required | `string` | -| `ownerId` | optional | `string` | -| `revision` | required | `number` | -| `status` | required | [`packages/experimental/agent-team/src/types.ts#TeamTaskStatus`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtaskstatus) | -| `subject` | required | `string` | -| `writeScopes` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | - - - -### `packages/experimental/agent-team/src/types.ts#TeamTaskStatus` - -SHA-256: `b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943` - -Sources: [`packages/experimental/agent-team/src/types.ts:71`](../packages/experimental/agent-team/src/types.ts) - -One of: - -- `"completed"` -- `"deleted"` -- `"in_progress"` -- `"pending"` - - - -### `packages/feedback/command-feedback/src/types.ts#FeedbackRecord` - -SHA-256: `7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344` - -Sources: [`packages/feedback/command-feedback/src/types.ts:27`](../packages/feedback/command-feedback/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `category` | optional | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | -| `text` | optional | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete` - -SHA-256: `7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06` - -Sources: [`packages/feedback/message-feedback/src/types.ts:46`](../packages/feedback/message-feedback/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `messageId` | required | `string` | -| `sessionId` | required | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem` - -SHA-256: `3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182` - -Sources: [`packages/feedback/message-feedback/src/types.ts:20`](../packages/feedback/message-feedback/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `category` | optional | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | -| `createdAt` | required | `number` | -| `messageId` | required | `string` | -| `note` | optional | `string` | -| `rating` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackrating) | -| `updatedAt` | required | `number` | -| `version` | required | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut` - -SHA-256: `aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626` - -Sources: [`packages/feedback/message-feedback/src/types.ts:38`](../packages/feedback/message-feedback/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `item` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackitem) | -| `sessionId` | required | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating` - -SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2` - -Sources: [`packages/feedback/message-feedback/src/types.ts:17`](../packages/feedback/message-feedback/src/types.ts) - -One of: - -- `"negative"` -- `"positive"` - - - -### `packages/goal/goal/src/domain.ts#GoalChangeMeta` - -SHA-256: `7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438` - -Sources: [`packages/goal/goal/src/domain.ts:44`](../packages/goal/goal/src/domain.ts) - -One of: - -- [`packages/goal/goal/src/domain.ts#GoalClearChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalclearchangemeta) -- [`packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalsnapshotchangemeta) - - - -### `packages/goal/goal/src/domain.ts#GoalClearChangeMeta` - -SHA-256: `cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f` - -Sources: [`packages/goal/goal/src/domain.ts:35`](../packages/goal/goal/src/domain.ts) - -| Property | Presence | Type | -|---|---|---| -| `cleared` | required | [`packages/goal/goal/src/types.ts#GoalRef`](#persistence-type-packagesgoalgoalsrctypestsgoalref) | -| `clearedAt` | required | `number` | -| `kind` | required | `"goal/change"` | -| `operation` | required | `"clear"` | -| `version` | required | `1` | - - - -### `packages/goal/goal/src/domain.ts#GoalMessageSource` - -SHA-256: `7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc` - -Sources: [`packages/goal/goal/src/domain.ts:47`](../packages/goal/goal/src/domain.ts) - -| Property | Presence | Type | -|---|---|---| -| `goalId` | required | `string` | -| `kind` | required | `"goal"` | -| `revision` | required | `number` | -| `round` | required | `number` | - - - -### `packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta` - -SHA-256: `1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4` - -Sources: [`packages/goal/goal/src/domain.ts:24`](../packages/goal/goal/src/domain.ts) - -| Property | Presence | Type | -|---|---|---| -| `createdAt` | required | `number` | -| `goal` | required | [`packages/goal/goal/src/types.ts#GoalSnapshot`](#persistence-type-packagesgoalgoalsrctypestsgoalsnapshot) | -| `kind` | required | `"goal/change"` | -| `operation` | required | [`event:goal/change.data[0].operation`](#persistence-type-eventgoalchangedata0operation) | -| `roundsStarted` | required | `number` | -| `updatedAt` | required | `number` | -| `version` | required | `1` | - - - -### `packages/goal/goal/src/types.ts#GoalBlockReason` - -SHA-256: `84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c` - -Sources: [`packages/goal/goal/src/types.ts:52`](../packages/goal/goal/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `code` | required | `string` | -| `message` | required | `string` | - - - -### `packages/goal/goal/src/types.ts#GoalPhase` - -SHA-256: `b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172` - -Sources: [`packages/goal/goal/src/types.ts:45`](../packages/goal/goal/src/types.ts) - -One of: - -- `"active"` -- `"blocked"` -- `"complete"` -- `"paused"` - - - -### `packages/goal/goal/src/types.ts#GoalRef` - -SHA-256: `0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f` - -Sources: [`packages/goal/goal/src/types.ts:20`](../packages/goal/goal/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `id` | required | `string` | -| `revision` | required | `number` | - - - -### `packages/goal/goal/src/types.ts#GoalSnapshot` - -SHA-256: `6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25` - -Sources: [`packages/goal/goal/src/types.ts:60`](../packages/goal/goal/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `blockedReason` | optional | [`packages/goal/goal/src/types.ts#GoalBlockReason`](#persistence-type-packagesgoalgoalsrctypestsgoalblockreason) | -| `id` | required | `string` | -| `maxGoalRounds` | required | `number` | -| `objective` | required | `string` | -| `phase` | required | [`packages/goal/goal/src/types.ts#GoalPhase`](#persistence-type-packagesgoalgoalsrctypestsgoalphase) | -| `revision` | required | `number` | - - - -### `packages/hooks/hook-protocol/src/types.ts#HookDialect` - -SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` - -Sources: [`packages/hooks/hook-protocol/src/types.ts:48`](../packages/hooks/hook-protocol/src/types.ts) - -One of: - -- `"claude-code"` -- `"codex"` - - - -### `packages/interaction/user-approval/src/index.ts#ApprovalPolicy` - -SHA-256: `05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf` - -Sources: [`packages/interaction/user-approval/src/index.ts:60`](../packages/interaction/user-approval/src/index.ts) - -One of: - -- `"ask"` -- `"never"` - - - -### `packages/interaction/user-approval/src/types.ts#ApprovalOutcome` - -SHA-256: `930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7` - -Sources: [`packages/interaction/user-approval/src/types.ts:32`](../packages/interaction/user-approval/src/types.ts) - -One of: - -- `"allowed-once"` -- `"cancelled"` -- `"rejected"` -- `"unavailable"` - - - -### `packages/llm/llm-retry/src/types.ts#LlmRetryEventData` - -SHA-256: `c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1` - -Sources: [`packages/llm/llm-retry/src/types.ts:16`](../packages/llm/llm-retry/src/types.ts) - -One of: - -- [`event:llm/retry.data[0]`](#persistence-type-eventllmretrydata0) -- [`event:llm/retry.data[1]`](#persistence-type-eventllmretrydata1) - - - -### `packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData` - -SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20` - -Sources: [`packages/llm/llm-retry/src/types.ts:43`](../packages/llm/llm-retry/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `retry` | required | `number` | -| `retryId` | required | `string` | -| `step` | required | `number` | -| `turn` | required | `number` | - - - -### `packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord` - -SHA-256: `86cf1e44038cb8b11659863dd0efafe682e41b9c782265c1d50e0a687debfc60` - -Sources: [`packages/llm/llm/src/assistant-stream.ts:20`](../packages/llm/llm/src/assistant-stream.ts) - -One of: - -- [`event:assistant/attempt.data.stream[0][2]`](#persistence-type-eventassistantattemptdatastream02) -- [`event:assistant/attempt.data.stream[0][3]`](#persistence-type-eventassistantattemptdatastream03) -- [`event:assistant/attempt.data.stream[0][1]`](#persistence-type-eventassistantattemptdatastream01) -- [`event:assistant/attempt.data.stream[0][0]`](#persistence-type-eventassistantattemptdatastream00) - - - -### `packages/llm/llm/src/call-config.ts#LlmCallConfig` - -SHA-256: `67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0` - -Sources: [`packages/llm/llm/src/call-config.ts:23`](../packages/llm/llm/src/call-config.ts) - -| Property | Presence | Type | -|---|---|---| -| `maxTokens` | optional | `number` | -| `model` | required | `string` | -| `provider` | required | `string` | -| `reasoningEffort` | optional | `string` | -| `stop` | optional | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `temperature` | optional | `number` | - - - -### `packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults` - -SHA-256: `326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693` - -Sources: [`packages/llm/llm/src/call-config.ts:36`](../packages/llm/llm/src/call-config.ts) - -| Property | Presence | Type | -|---|---|---| -| `maxTokens` | optional | `true` | -| `reasoningEffort` | optional | `true` | - - - -### `packages/llm/llm/src/message.ts#AssistantMessage` - -SHA-256: `e50b0a3ed8e6c80b672e4f855c91984f03b5c3fdd5d475bf171171f391a86c83` - -Sources: [`packages/llm/llm/src/message.ts:148`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | required | `string` | -| `role` | required | `"assistant"` | -| `source` | required | [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) | - - - -### `packages/llm/llm/src/message.ts#ContextSnapshotSection` - -SHA-256: `86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219` - -Sources: [`packages/llm/llm/src/message.ts:65`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `name` | required | `string` | -| `text` | required | `string` | - - - -### `packages/llm/llm/src/message.ts#Message` - -SHA-256: `23c7cce57d20589897f4e2bd5898affc6fc611b87cd0cc8b95be1cfdd8b3a7eb` - -Sources: [`packages/llm/llm/src/message.ts:131`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | required | `string` | -| `role` | required | [`event:session/title-llm-request.data.messages[0].role`](#persistence-type-eventsessiontitle-llm-requestdatamessages0role) | -| `source` | required | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | - - - -### `packages/llm/llm/src/message.ts#MessageSource` - -SHA-256: `4c965666d5b42116945bc356087cd5e1fd549e6dece560785ed60511059a8283` - -Sources: [`packages/llm/llm/src/message.ts:128`](../packages/llm/llm/src/message.ts) - -One of: - -- [`packages/context/agent-instructions/src/state.ts#AgentInstructionSource`](#persistence-type-packagescontextagent-instructionssrcstatetsagentinstructionsource) -- [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) -- [`event:agent/inbox/spliced.data.inserted[0].source[11]`](#persistence-type-eventagentinboxspliceddatainserted0source11) -- [`event:agent/inbox/spliced.data.inserted[0].source[19]`](#persistence-type-eventagentinboxspliceddatainserted0source19) -- [`packages/skill/tool-skill/src/index.ts#SkillCatalogSource`](#persistence-type-packagesskilltool-skillsrcindextsskillcatalogsource) -- [`packages/skill/skill/src/index.ts#SkillInvocationSource`](#persistence-type-packagesskillskillsrcindextsskillinvocationsource) -- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) -- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) -- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) -- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) -- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) -- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) -- [`packages/context/session-reference/src/types.ts#SessionReferenceSource`](#persistence-type-packagescontextsession-referencesrctypestssessionreferencesource) -- [`packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestssubagentsettledmessagesource) -- [`packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestsagentmessagesource) -- [`packages/goal/goal/src/domain.ts#GoalMessageSource`](#persistence-type-packagesgoalgoalsrcdomaintsgoalmessagesource) -- [`packages/experimental/agent-team/src/types.ts#TeamMessageSource`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesource) -- [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) -- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) -- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) - - - -### `packages/llm/llm/src/message.ts#ModelMessageSource` - -SHA-256: `719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91` - -Sources: [`packages/llm/llm/src/message.ts:24`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `kind` | required | `"model"` | -| `model` | required | `string` | -| `provider` | required | `string` | -| `replayState` | optional | `unknown` (opaque) | - - - -### `packages/llm/llm/src/message.ts#SystemMessage` - -SHA-256: `302b01ddddcbb3b16cfa3fba2a5d99f5082a55fbd9dc5c83a179a228b8a6a0ca` - -Sources: [`packages/llm/llm/src/message.ts:158`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | required | `string` | -| `role` | required | `"system"` | -| `source` | required | [`event:system/message.data.message.source`](#persistence-type-eventsystemmessagedatamessagesource) | - - - -### `packages/llm/llm/src/message.ts#ToolMessageSource` - -SHA-256: `d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab` - -Sources: [`packages/llm/llm/src/message.ts:29`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `callId` | required | `string` | -| `kind` | required | `"tool"` | - - - -### `packages/llm/llm/src/message.ts#ToolResultMessage` - -SHA-256: `1b573e2d5c094fa87e2a8bf409ddd4ac5ba92a123085e168de44b9ccdbd5244c` - -Sources: [`packages/llm/llm/src/message.ts:164`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:tool/result.data.message.content`](#persistence-type-eventtoolresultdatamessagecontent) | -| `id` | required | `string` | -| `role` | required | `"user"` | -| `source` | required | [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) | - - - -### `packages/llm/llm/src/message.ts#UserMessage` - -SHA-256: `4de5e7644130ed715ef6b5a4d86a87b30dca4096d1a6683c66acf6f7809379c7` - -Sources: [`packages/llm/llm/src/message.ts:143`](../packages/llm/llm/src/message.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | required | `string` | -| `role` | required | `"user"` | -| `source` | required | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | - - - -### `packages/llm/llm/src/types.ts#ContentBlock` - -SHA-256: `c7b24be059d34d08929593049a1a81eaa3855166aacfe9d7603c0bc8bb728d56` - -Sources: [`packages/llm/llm/src/types.ts:137`](../packages/llm/llm/src/types.ts) - -One of: - -- [`packages/llm/llm/src/types.ts#ReasoningBlock`](#persistence-type-packagesllmllmsrctypestsreasoningblock) -- [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) -- [`packages/llm/llm/src/types.ts#ToolCallBlock`](#persistence-type-packagesllmllmsrctypeststoolcallblock) -- [`packages/llm/llm/src/types.ts#ImageBlock`](#persistence-type-packagesllmllmsrctypestsimageblock) -- [`packages/llm/llm/src/types.ts#FileBlock`](#persistence-type-packagesllmllmsrctypestsfileblock) -- [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) - - - -### `packages/llm/llm/src/types.ts#ContentBlockType` - -SHA-256: `757013fff5879d73d5753d8d1120faab56110e88ac3932485ab7e034d9e9ce61` - -Sources: [`packages/llm/llm/src/types.ts:135`](../packages/llm/llm/src/types.ts) - -One of: - -- `"file"` -- `"image"` -- `"reasoning"` -- `"text"` -- `"tool-call"` -- `"tool-result"` - - - -### `packages/llm/llm/src/types.ts#FileBlock` - -SHA-256: `f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef` - -Sources: [`packages/llm/llm/src/types.ts:97`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `attachment` | required | [`packages/attachment/attachment/src/types.ts#FileAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsfileattachmentref) | -| `type` | required | `"file"` | - - - -### `packages/llm/llm/src/types.ts#FinishReason` - -SHA-256: `5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80` - -Sources: [`packages/llm/llm/src/types.ts:152`](../packages/llm/llm/src/types.ts) - -One of: - -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]`](#persistence-type-eventassistantattemptdatastream03chunk6reason3) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]`](#persistence-type-eventassistantattemptdatastream03chunk6reason4) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]`](#persistence-type-eventassistantattemptdatastream03chunk6reason0) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]`](#persistence-type-eventassistantattemptdatastream03chunk6reason1) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) - - - -### `packages/llm/llm/src/types.ts#ImageBlock` - -SHA-256: `12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7` - -Sources: [`packages/llm/llm/src/types.ts:78`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `attachment` | required | [`packages/attachment/attachment/src/types.ts#ImageAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsimageattachmentref) | -| `offloaded` | optional | `true` | -| `type` | required | `"image"` | - - - -### `packages/llm/llm/src/types.ts#LlmFailure` - -SHA-256: `5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca` - -Sources: [`packages/llm/llm/src/types.ts:40`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `code` | required | `string` | -| `message` | required | `string` | -| `offloadImages` | optional | `number` | -| `providerRetryAfterMs` | optional | `number` | -| `requestId` | optional | `string` | -| `status` | optional | `number` | - - - -### `packages/llm/llm/src/types.ts#ReasoningBlock` - -SHA-256: `814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e` - -Sources: [`packages/llm/llm/src/types.ts:67`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `text` | required | `string` | -| `type` | required | `"reasoning"` | - - - -### `packages/llm/llm/src/types.ts#ReplayEnvelope` - -SHA-256: `0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555` - -Sources: [`packages/llm/llm/src/types.ts:404`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `blocks` | optional | [`event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks`](#persistence-type-eventassistantattemptdatastream03chunk6replaystateblocks) | -| `response` | required | `unknown` (opaque) | - - - -### `packages/llm/llm/src/types.ts#StreamChunk` - -SHA-256: `071d92b9dac661fcc826c678cf64d188f26fb93aab79c627b11a03acdd34dfca` - -Sources: [`packages/llm/llm/src/types.ts:426`](../packages/llm/llm/src/types.ts) - -One of: - -- [`event:assistant/attempt.data.stream[0][3].chunk[3]`](#persistence-type-eventassistantattemptdatastream03chunk3) -- [`event:assistant/attempt.data.stream[0][3].chunk[4]`](#persistence-type-eventassistantattemptdatastream03chunk4) -- [`event:assistant/attempt.data.stream[0][3].chunk[0]`](#persistence-type-eventassistantattemptdatastream03chunk0) -- [`event:assistant/attempt.data.stream[0][3].chunk[2]`](#persistence-type-eventassistantattemptdatastream03chunk2) -- [`event:assistant/attempt.data.stream[0][3].chunk[1]`](#persistence-type-eventassistantattemptdatastream03chunk1) -- [`event:assistant/attempt.data.stream[0][3].chunk[6]`](#persistence-type-eventassistantattemptdatastream03chunk6) -- [`event:assistant/attempt.data.stream[0][3].chunk[5]`](#persistence-type-eventassistantattemptdatastream03chunk5) - - - -### `packages/llm/llm/src/types.ts#TokenUsage` - -SHA-256: `fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394` - -Sources: [`packages/llm/llm/src/types.ts:162`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `cacheReadTokens` | optional | `number` | -| `cacheWriteTokens` | optional | `number` | -| `inputTokens` | required | `number` | -| `outputTokens` | required | `number` | -| `reasoningTokens` | optional | `number` | -| `totalTokens` | optional | `number` | - - - -### `packages/llm/llm/src/types.ts#ToolCallBlock` - -SHA-256: `c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea` - -Sources: [`packages/llm/llm/src/types.ts:104`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `arguments` | required | `string` | -| `id` | required | `string` | -| `name` | required | `string` | -| `type` | required | `"tool-call"` | - - - -### `packages/llm/llm/src/types.ts#ToolResultBlock` - -SHA-256: `d61574d68558c5a184429e70b04da393dd5460bf5cc3ddef814546e659bd5127` - -Sources: [`packages/llm/llm/src/types.ts:114`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `isError` | optional | `boolean` | -| `toolCallId` | required | `string` | -| `type` | required | `"tool-result"` | - - - -### `packages/llm/llm/src/types.ts#ToolSchema` - -SHA-256: `7f5f2a8618c2ece530a18b1358b890fb57fb8c35705e47b66bff2296f8c6e889` - -Sources: [`packages/llm/llm/src/types.ts:447`](../packages/llm/llm/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `description` | required | `string` | -| `name` | required | `string` | -| `parameters` | required | [`event:request/header.data.header.tools[0].parameters`](#persistence-type-eventrequestheaderdataheadertools0parameters) | - - - -### `packages/sandbox/sandbox/src/index.ts#SandboxMode` - -SHA-256: `fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd` - -Sources: [`packages/sandbox/sandbox/src/index.ts:29`](../packages/sandbox/sandbox/src/index.ts) - -One of: - -- `"danger-full-access"` -- `"read-only"` -- `"workspace-write"` - - - -### `packages/schedule/schedule/src/types.ts#AfterScheduleRecord` - -SHA-256: `27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe` - -Sources: [`packages/schedule/schedule/src/types.ts:13`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `afterSeconds` | required | `number` | -| `id` | required | `string` | -| `kind` | required | `"after"` | -| `prompt` | required | `string` | -| `scheduledAt` | required | `string` | - - - -### `packages/schedule/schedule/src/types.ts#AtScheduleRecord` - -SHA-256: `658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e` - -Sources: [`packages/schedule/schedule/src/types.ts:27`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `id` | required | `string` | -| `kind` | required | `"at"` | -| `prompt` | required | `string` | -| `scheduledAt` | required | `string` | - - - -### `packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange` - -SHA-256: `e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344` - -Sources: [`packages/schedule/schedule/src/types.ts:93`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `acceptedAt` | required | `string` | -| `id` | required | `string` | -| `operation` | required | `"dispatch"` | -| `version` | required | `1` | - - - -### `packages/schedule/schedule/src/types.ts#EveryScheduleRecord` - -SHA-256: `66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14` - -Sources: [`packages/schedule/schedule/src/types.ts:39`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `everySeconds` | required | `number` | -| `id` | required | `string` | -| `kind` | required | `"every"` | -| `prompt` | required | `string` | -| `scheduledAt` | required | `string` | - - - -### `packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange` - -SHA-256: `8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af` - -Sources: [`packages/schedule/schedule/src/types.ts:86`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `id` | required | `string` | -| `operation` | required | `"dispatch"` | -| `version` | required | `1` | - - - -### `packages/schedule/schedule/src/types.ts#ScheduleChange` - -SHA-256: `e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1` - -Sources: [`packages/schedule/schedule/src/types.ts:105`](../packages/schedule/schedule/src/types.ts) - -One of: - -- [`packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestseveryscheduledispatchchange) -- [`packages/schedule/schedule/src/types.ts#ScheduleDeleteChange`](#persistence-type-packagesscheduleschedulesrctypestsscheduledeletechange) -- [`packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestsoneshotscheduledispatchchange) -- [`packages/schedule/schedule/src/types.ts#ScheduleCreateChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulecreatechange) - - - -### `packages/schedule/schedule/src/types.ts#ScheduleCreateChange` - -SHA-256: `ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f` - -Sources: [`packages/schedule/schedule/src/types.ts:72`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `operation` | required | `"create"` | -| `schedule` | required | [`packages/schedule/schedule/src/types.ts#ScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsschedulerecord) | -| `version` | required | `1` | - - - -### `packages/schedule/schedule/src/types.ts#ScheduleDeleteChange` - -SHA-256: `18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0` - -Sources: [`packages/schedule/schedule/src/types.ts:79`](../packages/schedule/schedule/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `id` | required | `string` | -| `operation` | required | `"delete"` | -| `version` | required | `1` | - - - -### `packages/schedule/schedule/src/types.ts#ScheduleRecord` - -SHA-256: `d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87` - -Sources: [`packages/schedule/schedule/src/types.ts:69`](../packages/schedule/schedule/src/types.ts) - -One of: - -- [`packages/schedule/schedule/src/types.ts#AfterScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsafterschedulerecord) -- [`packages/schedule/schedule/src/types.ts#EveryScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestseveryschedulerecord) -- [`packages/schedule/schedule/src/types.ts#AtScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsatschedulerecord) - - - -### `packages/session/session-persistence-jsonl/src/format.ts#HeaderLine` - -SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` - -Sources: [`packages/session/session-persistence-jsonl/src/format.ts:82`](../packages/session/session-persistence-jsonl/src/format.ts) - -| Property | Presence | Type | -|---|---|---| -| `agentPreset` | optional | `string` | -| `createdAt` | required | `number` | -| `cwd` | optional | `string` | -| `delegationDepth` | required | `number` | -| `id` | required | `string` | -| `isSeeded` | required | `boolean` | -| `origin` | optional | `"subagent"` | -| `parentSession` | optional | `string` | -| `type` | required | `"session"` | -| `version` | required | `number` | - - - -### `packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData` - -SHA-256: `9fe0e77a7816b7fdb4b953ec0e2f0cd7bbd22c5de5c3567e612d1b20eb0992e6` - -Sources: [`packages/session/session-title-llm/src/index.ts:27`](../packages/session/session-title-llm/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| `maxTokens` | required | `number` | -| `messageSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `messages` | required | [`event:session/title-llm-request.data.messages`](#persistence-type-eventsessiontitle-llm-requestdatamessages) | -| `route` | required | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | -| `system` | required | `string` | -| `titleProvider` | required | `string` | - - - -### `packages/session/session-title/src/types.ts#SessionTitleEventData` - -SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4` - -Sources: [`packages/session/session-title/src/types.ts:41`](../packages/session/session-title/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `messageSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `source` | required | [`packages/session/session-title/src/types.ts#SessionTitleSource`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlesource) | -| `title` | required | `string` | - - - -### `packages/session/session-title/src/types.ts#SessionTitleModelIdentity` - -SHA-256: `07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235` - -Sources: [`packages/session/session-title/src/types.ts:20`](../packages/session/session-title/src/types.ts) · [`packages/subagent/tool-subagent/src/model-selection.ts:9`](../packages/subagent/tool-subagent/src/model-selection.ts) - -| Property | Presence | Type | -|---|---|---| -| `model` | required | `string` | -| `provider` | required | `string` | - - - -### `packages/session/session-title/src/types.ts#SessionTitleSource` - -SHA-256: `30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f` - -Sources: [`packages/session/session-title/src/types.ts:28`](../packages/session/session-title/src/types.ts) - -One of: - -- [`event:session/title.data.source[1]`](#persistence-type-eventsessiontitledatasource1) -- [`event:session/title.data.source[0]`](#persistence-type-eventsessiontitledatasource0) -- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) - - - -### `packages/skill/skill/src/index.ts#SkillInvocationSource` - -SHA-256: `672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db` - -Sources: [`packages/skill/skill/src/index.ts:146`](../packages/skill/skill/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"instructions"` | -| `kind` | required | `"skill-invocation"` | -| `name` | required | `string` | - - - -### `packages/skill/tool-skill/src/index.ts#SkillCatalogSource` - -SHA-256: `fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093` - -Sources: [`packages/skill/tool-skill/src/index.ts:34`](../packages/skill/tool-skill/src/index.ts) - -| Property | Presence | Type | -|---|---|---| -| `entries` | required | [`event:agent/inbox/spliced.data.inserted[0].source[17].entries`](#persistence-type-eventagentinboxspliceddatainserted0source17entries) | -| `form` | required | `"catalog"` | -| `kind` | required | `"skill-catalog"` | -| `update` | optional | `true` | - - - -### `packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent` - -SHA-256: `3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e` - -Sources: [`packages/subagent/subagent/src/catalog.ts:24`](../packages/subagent/subagent/src/catalog.ts) - -One of: - -- [`event:subagent/catalog.data[1]`](#persistence-type-eventsubagentcatalogdata1) -- [`event:subagent/catalog.data[0]`](#persistence-type-eventsubagentcatalogdata0) - - - -### `packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource` - -SHA-256: `4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86` - -Sources: [`packages/subagent/subagent/src/continuation-messages.ts:15`](../packages/subagent/subagent/src/continuation-messages.ts) - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"relay"` | -| `kind` | required | `"agent-message"` | -| `senderSessionId` | required | `string` | - - - -### `packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource` - -SHA-256: `4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a` - -Sources: [`packages/subagent/subagent/src/continuation-messages.ts:30`](../packages/subagent/subagent/src/continuation-messages.ts) - -| Property | Presence | Type | -|---|---|---| -| `form` | required | `"notice"` | -| `kind` | required | `"subagent-settled"` | -| `senderSessionId` | required | `string` | -| `summary` | required | `string` | - - - -### `packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData` - -SHA-256: `6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f` - -Sources: [`packages/subagent/subagent/src/descriptor.ts:72`](../packages/subagent/subagent/src/descriptor.ts) - -| Property | Presence | Type | -|---|---|---| -| `agentModel` | optional | `string` | -| `agentProvider` | optional | `string` | -| `agentReasoningEffort` | optional | `string` | -| `label` | required | `string` | -| `mode` | required | `"continuable"` | -| `persona` | optional | `string` | -| `provider` | required | `string` | -| `toolFilter` | optional | [`packages/core/tools/src/index.ts#ToolRestriction`](#persistence-type-packagescoretoolssrcindextstoolrestriction) | -| `version` | required | `number` | - - - -### `packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData` - -SHA-256: `5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564` - -Sources: [`packages/subagent/subagent/src/descriptor.ts:61`](../packages/subagent/subagent/src/descriptor.ts) - -| Property | Presence | Type | -|---|---|---| -| `label` | optional | `string` | -| `mode` | required | `"one-shot"` | -| `provider` | required | `string` | -| `version` | required | `number` | - - - -### `packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData` - -SHA-256: `86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde` - -Sources: [`packages/subagent/subagent/src/descriptor.ts:89`](../packages/subagent/subagent/src/descriptor.ts) - -One of: - -- [`packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortscontinuablesubagentdescriptordata) -- [`packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortsoneshotsubagentdescriptordata) - - - -### `packages/todo/tool-todo/src/types.ts#TodoItem` - -SHA-256: `a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a` - -Sources: [`packages/todo/tool-todo/src/types.ts:21`](../packages/todo/tool-todo/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `content` | required | `string` | -| `status` | required | [`event:todo/write.data.todos[0].status`](#persistence-type-eventtodowritedatatodos0status) | - - - -### `packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest` - -SHA-256: `2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9` - -Sources: [`packages/web/web-search-deepseek/src/provider.ts:55`](../packages/web/web-search-deepseek/src/provider.ts) - -| Property | Presence | Type | -|---|---|---| -| `apiVersion` | required | `string` | -| `body` | required | [`event:web/deepseek-search-llm-request.data.body`](#persistence-type-eventwebdeepseek-search-llm-requestdatabody) | -| `endpoint` | required | `string` | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData` - -SHA-256: `c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7` - -Sources: [`packages/workflow/tool-workflow/src/types.ts:29`](../packages/workflow/tool-workflow/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `outcome` | required | [`packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowagentoutcome) | -| `runId` | required | `string` | -| `seq` | required | `number` | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData` - -SHA-256: `9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc` - -Sources: [`packages/workflow/tool-workflow/src/types.ts:20`](../packages/workflow/tool-workflow/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `childId` | required | `string` | -| `label` | required | `string` | -| `phase` | optional | `string` | -| `runId` | required | `string` | -| `seq` | required | `number` | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData` - -SHA-256: `7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462` - -Sources: [`packages/workflow/tool-workflow/src/types.ts:36`](../packages/workflow/tool-workflow/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `runId` | required | `string` | -| `stopReason` | required | [`packages/workflow/workflow/src/types.ts#WorkflowStopReason`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowstopreason) | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData` - -SHA-256: `a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c` - -Sources: [`packages/workflow/tool-workflow/src/types.ts:14`](../packages/workflow/tool-workflow/src/types.ts) - -| Property | Presence | Type | -|---|---|---| -| `name` | required | `string` | -| `runId` | required | `string` | - - - -### `packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome` - -SHA-256: `c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896` - -Sources: [`packages/workflow/workflow/src/types.ts:110`](../packages/workflow/workflow/src/types.ts) - -One of: - -- `"cancelled"` -- `"completed"` -- `"failed"` - - - -### `packages/workflow/workflow/src/types.ts#WorkflowStopReason` - -SHA-256: `8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15` - -Sources: [`packages/workflow/workflow/src/types.ts:63`](../packages/workflow/workflow/src/types.ts) - -One of: - -- `"cancelled"` -- `"completed"` -- `"error"` - - - -### `"parent"` - -SHA-256: `e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732` - -`"parent"` - - - -### `"pause"` - -SHA-256: `1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721` - -`"pause"` - - - -### `"paused"` - -SHA-256: `c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943` - -`"paused"` - - - -### `"pending"` - -SHA-256: `234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85` - -`"pending"` - - - -### `"permission/preset"` - -SHA-256: `ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649` - -`"permission/preset"` - - - -### `"plan/mode"` - -SHA-256: `f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9` - -`"plan/mode"` - - - -### `"plugin"` - -SHA-256: `e654d28d1e6c471147310d2fba396d00969cfe6ed9022626d3f2c2312e0b1cbb` - -`"plugin"` - - - -### `"positive"` - -SHA-256: `df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528` - -`"positive"` - - - -### `"product-interaction"` - -SHA-256: `0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23` - -`"product-interaction"` - - - -### `"provider"` - -SHA-256: `e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a` - -`"provider"` - - - -### `"provisioning"` - -SHA-256: `871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62` - -`"provisioning"` - - - -### `"read-only"` - -SHA-256: `12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42` - -`"read-only"` - - - -### `"reasoning"` - -SHA-256: `3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c` - -`"reasoning"` - - - -### `"reasoning-chunks"` - -SHA-256: `688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8` - -`"reasoning-chunks"` - - - -### `"reasoning-delta"` - -SHA-256: `6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6` - -`"reasoning-delta"` - - - -### `"recall"` - -SHA-256: `383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f` - -`"recall"` - - - -### `"rejected"` - -SHA-256: `fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018` - -`"rejected"` - - - -### `"relay"` - -SHA-256: `16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e` - -`"relay"` - - - -### `"remove"` - -SHA-256: `7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc` - -`"remove"` - - - -### `"replace"` - -SHA-256: `f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8` - -`"replace"` - - - -### `"request/context"` - -SHA-256: `70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2` - -`"request/context"` - - - -### `"request/header"` - -SHA-256: `3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e` - -`"request/header"` - - - -### `"resource-cost"` - -SHA-256: `5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75` - -`"resource-cost"` - - - -### `"resume"` - -SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66` - -`"resume"` - - - -### `"sandbox/mode"` - -SHA-256: `ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2` - -`"sandbox/mode"` - - - -### `"schedule/change"` - -SHA-256: `0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d` - -`"schedule/change"` - - - -### `"security-privacy-permission"` - -SHA-256: `07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7` - -`"security-privacy-permission"` - - - -### `"series"` - -SHA-256: `4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f` - -`"series"` - - - -### `"service-stability"` - -SHA-256: `7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732` - -`"service-stability"` - - - -### `"session"` - -SHA-256: `e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828` - -`"session"` - - - -### `"session-log-deepseek/delivery-accepted"` - -SHA-256: `47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b` - -`"session-log-deepseek/delivery-accepted"` - - - -### `"session-reference"` - -SHA-256: `7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71` - -`"session-reference"` - - - -### `"session/end-seed"` - -SHA-256: `1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330` - -`"session/end-seed"` - - - -### `SessionEventEnvelope` - -SHA-256: `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` - -One of: - -- [`SessionEventEnvelope[39]`](#persistence-type-sessioneventenvelope39) -- [`SessionEventEnvelope[6]`](#persistence-type-sessioneventenvelope6) -- [`SessionEventEnvelope[0]`](#persistence-type-sessioneventenvelope0) - - - -### `SessionEventEnvelope[0]` - -SHA-256: `e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f` - -| Property | Presence | Type | -|---|---|---| -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `time` | required | `number` | -| `type` | required | `string` | - - - -### `SessionEventEnvelope[39]` - -SHA-256: `998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0` - -| Property | Presence | Type | -|---|---|---| -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | required | `number` | -| `type` | required | `string` | - - - -### `SessionEventEnvelope[39].sourceEventSeqs` - -SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` - -Array of `number`. - - - -### `SessionEventEnvelope[6]` - -SHA-256: `7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb` +SHA-256: `0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f` | Property | Presence | Type | |---|---|---| -| `ignorable` | optional | `true` | -| `seq` | required | `number` | -| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | required | `number` | -| `type` | required | `string` | +| [`string`] | index signature | `unknown` (opaque) | - + -### `SessionEventEnvelope[6].surfaceOp[1]` +### `{}` -SHA-256: `bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825` +SHA-256: `529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05` -Sources: [`packages/core/session/src/types.ts:441`](../packages/core/session/src/types.ts) +Sources: [`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) | Property | Presence | Type | |---|---|---| -| `endSeq` | required | `number` | -| `op` | required | `"replace"` | -| `startSeq` | required | `number` | - - - -### `"session/title"` - -SHA-256: `7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50` - -`"session/title"` - - - -### `"session/title-llm-request"` - -SHA-256: `587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e` - -`"session/title-llm-request"` - - - -### `"set"` - -SHA-256: `b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b` - -`"set"` - - - -### `"skill-catalog"` - -SHA-256: `6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3` - -`"skill-catalog"` - - - -### `"skill-invocation"` - -SHA-256: `1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509` - -`"skill-invocation"` - - - -### `"snapshot"` - -SHA-256: `6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912` - -`"snapshot"` - - - -### `"step/end"` - -SHA-256: `c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70` - -`"step/end"` - - - -### `"step/start"` - -SHA-256: `2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d` - -`"step/start"` - - - -### `"stop"` - -SHA-256: `57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90` - -`"stop"` - - - -### `string` - -SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` - -Sources: [`packages/api/session-controller/src/types.ts:376`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:19`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:10`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/webhook/webhook/src/brand.ts:12`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:6`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:9`](../packages/webhook/webhook/src/brand.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) - -`string` - - - -### `"subagent"` - -SHA-256: `aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6` - -`"subagent"` - - - -### `"subagent-settled"` - -SHA-256: `bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a` - -`"subagent-settled"` - - - -### `"subagent/catalog"` - -SHA-256: `44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2` - -`"subagent/catalog"` - - - -### `"subagent/descriptor"` - -SHA-256: `5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647` - -`"subagent/descriptor"` - - - -### `"subagent/model-selection-policy"` - -SHA-256: `0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da` - -`"subagent/model-selection-policy"` - - - -### `"success"` - -SHA-256: `511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7` - -`"success"` - - - -### `"system"` - -SHA-256: `8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3` - -`"system"` - - - -### `"system/message"` - -SHA-256: `1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7` - -`"system/message"` - - - -### `"task-result"` - -SHA-256: `f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c` - -`"task-result"` - - - -### `"team-message"` - -SHA-256: `2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c` - -`"team-message"` - - - -### `"team/member"` - -SHA-256: `18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0` - -`"team/member"` - - - -### `"team/message/delivered"` - -SHA-256: `a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57` - -`"team/message/delivered"` - - - -### `"team/message/queued"` - -SHA-256: `4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159` - -`"team/message/queued"` - - - -### `"team/task"` - -SHA-256: `b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b` - -`"team/task"` - - - -### `"text"` - -SHA-256: `4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d` - -`"text"` - - - -### `"text-chunks"` - -SHA-256: `f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3` - -`"text-chunks"` - - - -### `"text-delta"` - -SHA-256: `5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563` - -`"text-delta"` - - - -### `"todo/write"` - -SHA-256: `af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7` - -`"todo/write"` - - - -### `"tool"` - -SHA-256: `a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847` - -`"tool"` - - - -### `"tool-call"` - -SHA-256: `1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7` - -`"tool-call"` - - - -### `"tool-call-chunks"` - -SHA-256: `616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5` - -`"tool-call-chunks"` - - - -### `"tool-call-delta"` - -SHA-256: `9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267` - -`"tool-call-delta"` - - - -### `"tool-calls"` - -SHA-256: `6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b` - -`"tool-calls"` - - - -### `"tool-result"` - -SHA-256: `e5244812c495a80c2e78ba2c2690dca5f6b58ea8d3fe5531ff94a6f9ac5e5d66` - -`"tool-result"` - - - -### `"tool-workflow/agent-end"` - -SHA-256: `5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e` - -`"tool-workflow/agent-end"` - - - -### `"tool-workflow/agent-start"` - -SHA-256: `ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8` - -`"tool-workflow/agent-start"` - - - -### `"tool-workflow/run-end"` - -SHA-256: `fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd` - -`"tool-workflow/run-end"` - - - -### `"tool-workflow/run-start"` - -SHA-256: `cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670` - -`"tool-workflow/run-start"` - - - -### `"tool/call"` - -SHA-256: `c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92` - -`"tool/call"` - - - -### `"tool/ptc-dispatch"` - -SHA-256: `fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973` - -`"tool/ptc-dispatch"` - - - -### `"tool/ptc-dispatch-start"` - -SHA-256: `2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456` - -`"tool/ptc-dispatch-start"` - - - -### `"tool/result"` - -SHA-256: `570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833` - -`"tool/result"` - - - -### `true` - -SHA-256: `dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521` - -`true` - - - -### `"turn/end"` - -SHA-256: `4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03` - -`"turn/end"` - - - -### `"turn/start"` - -SHA-256: `0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f` - -`"turn/start"` - - - -### `"unavailable"` - -SHA-256: `2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c` - -`"unavailable"` - - - -### `unknown` - -SHA-256: `bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d` - -`unknown`: the declaration does not expose the stored value's internal fields. - - - -### `"usage"` - -SHA-256: `0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9` - -`"usage"` - - - -### `"user"` - -SHA-256: `68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573` - -`"user"` - - - -### `"user/message"` - -SHA-256: `de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f` - -`"user/message"` - - - -### `"web_search"` - -SHA-256: `935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682` - -`"web_search"` - - - -### `"web_search_20250305"` - -SHA-256: `0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e` - -`"web_search_20250305"` - - - -### `"web/deepseek-search-llm-request"` - -SHA-256: `6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675` - -`"web/deepseek-search-llm-request"` - - - -### `"webhook"` - -SHA-256: `db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0` - -`"webhook"` - - - -### `"workspace-write"` - -SHA-256: `a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa` - -`"workspace-write"` - - - -### `"workspace/changes"` - -SHA-256: `8e8155594e07812356b67d732196dda894b0f9c91a5969d51612cf490b0a016d` - -`"workspace/changes"` +| [`string`] | index signature | [`JsonValue`](#persistence-type-sha256-c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6) | diff --git a/docs/persistence-catalog.zh.md b/docs/persistence-catalog.zh.md index 91ca2f7a03..c655d97086 100644 --- a/docs/persistence-catalog.zh.md +++ b/docs/persistence-catalog.zh.md @@ -19,67 +19,68 @@ | 根类型 | 类别 | SHA-256 | 已解析类型 | |---|---|---|---| -| `SessionHeader` | header | `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` | [`packages/core/session/src/types.ts#SessionHeader`](#persistence-type-packagescoresessionsrctypestssessionheader) | -| `JsonlHeaderLine` | header | `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` | [`packages/session/session-persistence-jsonl/src/format.ts#HeaderLine`](#persistence-type-packagessessionsession-persistence-jsonlsrcformattsheaderline) | -| `SessionEventEnvelope` | envelope | `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` | [`SessionEventEnvelope`](#persistence-type-sessioneventenvelope) | -| `event:agent-preset/selected` | event | `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` | [`event:agent-preset/selected`](#persistence-type-eventagent-presetselected) | -| `event:agent/inbox/spliced` | event | `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` | [`event:agent/inbox/spliced`](#persistence-type-eventagentinboxspliced) | -| `event:approval/asked` | event | `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` | [`event:approval/asked`](#persistence-type-eventapprovalasked) | -| `event:approval/decided` | event | `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` | [`event:approval/decided`](#persistence-type-eventapprovaldecided) | -| `event:approval/policy` | event | `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` | [`event:approval/policy`](#persistence-type-eventapprovalpolicy) | -| `event:assistant/attempt` | event | `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` | [`event:assistant/attempt`](#persistence-type-eventassistantattempt) | -| `event:assistant/message` | event | `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` | [`event:assistant/message`](#persistence-type-eventassistantmessage) | -| `event:command/done` | event | `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` | [`event:command/done`](#persistence-type-eventcommanddone) | -| `event:command/run` | event | `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` | [`event:command/run`](#persistence-type-eventcommandrun) | -| `event:compaction/end` | event | `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` | [`event:compaction/end`](#persistence-type-eventcompactionend) | -| `event:compaction/prune` | event | `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` | [`event:compaction/prune`](#persistence-type-eventcompactionprune) | -| `event:compaction/start` | event | `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` | [`event:compaction/start`](#persistence-type-eventcompactionstart) | -| `event:compaction/summary` | event | `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` | [`event:compaction/summary`](#persistence-type-eventcompactionsummary) | -| `event:deliverables/presented` | event | `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` | [`event:deliverables/presented`](#persistence-type-eventdeliverablespresented) | -| `event:feedback/message-delete` | event | `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` | [`event:feedback/message-delete`](#persistence-type-eventfeedbackmessage-delete) | -| `event:feedback/message-put` | event | `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` | [`event:feedback/message-put`](#persistence-type-eventfeedbackmessage-put) | -| `event:feedback/record` | event | `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` | [`event:feedback/record`](#persistence-type-eventfeedbackrecord) | -| `event:goal/change` | event | `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` | [`event:goal/change`](#persistence-type-eventgoalchange) | -| `event:hook/invoked` | event | `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` | [`event:hook/invoked`](#persistence-type-eventhookinvoked) | -| `event:hook/result` | event | `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` | [`event:hook/result`](#persistence-type-eventhookresult) | -| `event:image/offload` | event | `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` | [`event:image/offload`](#persistence-type-eventimageoffload) | -| `event:llm/retry` | event | `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` | [`event:llm/retry`](#persistence-type-eventllmretry) | -| `event:llm/retry-started` | event | `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` | [`event:llm/retry-started`](#persistence-type-eventllmretry-started) | -| `event:model/selection` | event | `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` | [`event:model/selection`](#persistence-type-eventmodelselection) | -| `event:permission/preset` | event | `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` | [`event:permission/preset`](#persistence-type-eventpermissionpreset) | -| `event:plan/mode` | event | `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` | [`event:plan/mode`](#persistence-type-eventplanmode) | -| `event:request/context` | event | `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` | [`event:request/context`](#persistence-type-eventrequestcontext) | -| `event:request/header` | event | `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` | [`event:request/header`](#persistence-type-eventrequestheader) | -| `event:sandbox/mode` | event | `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` | [`event:sandbox/mode`](#persistence-type-eventsandboxmode) | -| `event:schedule/change` | event | `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` | [`event:schedule/change`](#persistence-type-eventschedulechange) | -| `event:session-log-deepseek/delivery-accepted` | event | `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` | [`event:session-log-deepseek/delivery-accepted`](#persistence-type-eventsession-log-deepseekdelivery-accepted) | -| `event:session/end-seed` | event | `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` | [`event:session/end-seed`](#persistence-type-eventsessionend-seed) | -| `event:session/title` | event | `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` | [`event:session/title`](#persistence-type-eventsessiontitle) | -| `event:session/title-llm-request` | event | `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` | [`event:session/title-llm-request`](#persistence-type-eventsessiontitle-llm-request) | -| `event:step/end` | event | `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` | [`event:step/end`](#persistence-type-eventstepend) | -| `event:step/start` | event | `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` | [`event:step/start`](#persistence-type-eventstepstart) | -| `event:subagent/catalog` | event | `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` | [`event:subagent/catalog`](#persistence-type-eventsubagentcatalog) | -| `event:subagent/descriptor` | event | `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` | [`event:subagent/descriptor`](#persistence-type-eventsubagentdescriptor) | -| `event:subagent/model-selection-policy` | event | `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` | [`event:subagent/model-selection-policy`](#persistence-type-eventsubagentmodel-selection-policy) | -| `event:system/message` | event | `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` | [`event:system/message`](#persistence-type-eventsystemmessage) | -| `event:team/member` | event | `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` | [`event:team/member`](#persistence-type-eventteammember) | -| `event:team/message/delivered` | event | `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` | [`event:team/message/delivered`](#persistence-type-eventteammessagedelivered) | -| `event:team/message/queued` | event | `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` | [`event:team/message/queued`](#persistence-type-eventteammessagequeued) | -| `event:team/task` | event | `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` | [`event:team/task`](#persistence-type-eventteamtask) | -| `event:todo/write` | event | `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` | [`event:todo/write`](#persistence-type-eventtodowrite) | -| `event:tool-workflow/agent-end` | event | `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` | [`event:tool-workflow/agent-end`](#persistence-type-eventtool-workflowagent-end) | -| `event:tool-workflow/agent-start` | event | `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` | [`event:tool-workflow/agent-start`](#persistence-type-eventtool-workflowagent-start) | -| `event:tool-workflow/run-end` | event | `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` | [`event:tool-workflow/run-end`](#persistence-type-eventtool-workflowrun-end) | -| `event:tool-workflow/run-start` | event | `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` | [`event:tool-workflow/run-start`](#persistence-type-eventtool-workflowrun-start) | -| `event:tool/call` | event | `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` | [`event:tool/call`](#persistence-type-eventtoolcall) | -| `event:tool/ptc-dispatch` | event | `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` | [`event:tool/ptc-dispatch`](#persistence-type-eventtoolptc-dispatch) | -| `event:tool/ptc-dispatch-start` | event | `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` | [`event:tool/ptc-dispatch-start`](#persistence-type-eventtoolptc-dispatch-start) | -| `event:tool/result` | event | `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` | [`event:tool/result`](#persistence-type-eventtoolresult) | -| `event:turn/end` | event | `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` | [`event:turn/end`](#persistence-type-eventturnend) | -| `event:turn/start` | event | `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` | [`event:turn/start`](#persistence-type-eventturnstart) | -| `event:user/message` | event | `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` | [`event:user/message`](#persistence-type-eventusermessage) | -| `event:web/deepseek-search-llm-request` | event | `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` | [`event:web/deepseek-search-llm-request`](#persistence-type-eventwebdeepseek-search-llm-request) | -| `event:workspace/changes` | event | `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | [`event:workspace/changes`](#persistence-type-eventworkspacechanges) | +| `SessionHeader` | header | `1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445` | [`SessionHeader`](#persistence-type-sha256-1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445) | +| `JsonlHeaderLine` | header | `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` | [`HeaderLine`](#persistence-type-sha256-18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f) | +| `SessionEventEnvelope` | envelope | `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` | [`union (3 variants)`](#persistence-type-sha256-5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc) | +| `event:agent-preset/selected` | event | `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` | [`{ type: "agent-preset/selected" }`](#persistence-type-sha256-a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b) | +| `event:agent/inbox/spliced` | event | `1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c` | [`{ type: "agent/inbox/spliced" }`](#persistence-type-sha256-1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c) | +| `event:approval/asked` | event | `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` | [`{ type: "approval/asked" }`](#persistence-type-sha256-3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1) | +| `event:approval/decided` | event | `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` | [`{ type: "approval/decided" }`](#persistence-type-sha256-bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3) | +| `event:approval/policy` | event | `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` | [`{ type: "approval/policy" }`](#persistence-type-sha256-26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78) | +| `event:assistant/attempt` | event | `15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4` | [`{ type: "assistant/attempt" }`](#persistence-type-sha256-15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4) | +| `event:assistant/message` | event | `1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625` | [`{ type: "assistant/message" }`](#persistence-type-sha256-1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625) | +| `event:command/done` | event | `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` | [`{ type: "command/done" }`](#persistence-type-sha256-15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff) | +| `event:command/run` | event | `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` | [`{ type: "command/run" }`](#persistence-type-sha256-37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006) | +| `event:compaction/end` | event | `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` | [`{ type: "compaction/end" }`](#persistence-type-sha256-b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d) | +| `event:compaction/prune` | event | `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` | [`{ type: "compaction/prune" }`](#persistence-type-sha256-7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04) | +| `event:compaction/start` | event | `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` | [`{ type: "compaction/start" }`](#persistence-type-sha256-db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965) | +| `event:compaction/summary` | event | `e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602` | [`{ type: "compaction/summary" }`](#persistence-type-sha256-e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602) | +| `event:deliverables/presented` | event | `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` | [`{ type: "deliverables/presented" }`](#persistence-type-sha256-13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176) | +| `event:developer/message` | event | `eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80` | [`{ type: "developer/message" }`](#persistence-type-sha256-eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80) | +| `event:feedback/message-delete` | event | `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` | [`{ type: "feedback/message-delete" }`](#persistence-type-sha256-3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796) | +| `event:feedback/message-put` | event | `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` | [`{ type: "feedback/message-put" }`](#persistence-type-sha256-b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf) | +| `event:feedback/record` | event | `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` | [`{ type: "feedback/record" }`](#persistence-type-sha256-b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8) | +| `event:goal/change` | event | `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` | [`{ type: "goal/change" }`](#persistence-type-sha256-763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d) | +| `event:hook/invoked` | event | `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` | [`{ type: "hook/invoked" }`](#persistence-type-sha256-8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0) | +| `event:hook/result` | event | `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` | [`{ type: "hook/result" }`](#persistence-type-sha256-e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4) | +| `event:image/offload` | event | `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` | [`{ type: "image/offload" }`](#persistence-type-sha256-b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e) | +| `event:llm/retry` | event | `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` | [`{ type: "llm/retry" }`](#persistence-type-sha256-525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336) | +| `event:llm/retry-started` | event | `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` | [`{ type: "llm/retry-started" }`](#persistence-type-sha256-48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3) | +| `event:model/selection` | event | `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` | [`{ type: "model/selection" }`](#persistence-type-sha256-35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc) | +| `event:permission/preset` | event | `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` | [`{ type: "permission/preset" }`](#persistence-type-sha256-5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b) | +| `event:plan/mode` | event | `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` | [`{ type: "plan/mode" }`](#persistence-type-sha256-a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f) | +| `event:request/context` | event | `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` | [`{ type: "request/context" }`](#persistence-type-sha256-37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf) | +| `event:request/header` | event | `4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41` | [`{ type: "request/header" }`](#persistence-type-sha256-4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41) | +| `event:sandbox/mode` | event | `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` | [`{ type: "sandbox/mode" }`](#persistence-type-sha256-516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415) | +| `event:schedule/change` | event | `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` | [`{ type: "schedule/change" }`](#persistence-type-sha256-2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42) | +| `event:session-log-deepseek/delivery-accepted` | event | `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` | [`{ type: "session-log-deepseek/delivery-accepted" }`](#persistence-type-sha256-d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9) | +| `event:session/end-seed` | event | `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` | [`{ type: "session/end-seed" }`](#persistence-type-sha256-5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e) | +| `event:session/title` | event | `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` | [`{ type: "session/title" }`](#persistence-type-sha256-1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5) | +| `event:session/title-llm-request` | event | `fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d` | [`{ type: "session/title-llm-request" }`](#persistence-type-sha256-fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d) | +| `event:step/end` | event | `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` | [`{ type: "step/end" }`](#persistence-type-sha256-e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05) | +| `event:step/start` | event | `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` | [`{ type: "step/start" }`](#persistence-type-sha256-4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986) | +| `event:subagent/catalog` | event | `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` | [`{ type: "subagent/catalog" }`](#persistence-type-sha256-ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871) | +| `event:subagent/descriptor` | event | `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` | [`{ type: "subagent/descriptor" }`](#persistence-type-sha256-b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5) | +| `event:subagent/model-selection-policy` | event | `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` | [`{ type: "subagent/model-selection-policy" }`](#persistence-type-sha256-a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc) | +| `event:system/message` | event | `69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1` | [`{ type: "system/message" }`](#persistence-type-sha256-69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1) | +| `event:team/member` | event | `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` | [`{ type: "team/member" }`](#persistence-type-sha256-4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc) | +| `event:team/message/delivered` | event | `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` | [`{ type: "team/message/delivered" }`](#persistence-type-sha256-48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb) | +| `event:team/message/queued` | event | `21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d` | [`{ type: "team/message/queued" }`](#persistence-type-sha256-21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d) | +| `event:team/task` | event | `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` | [`{ type: "team/task" }`](#persistence-type-sha256-d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a) | +| `event:todo/write` | event | `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` | [`{ type: "todo/write" }`](#persistence-type-sha256-b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26) | +| `event:tool-workflow/agent-end` | event | `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` | [`{ type: "tool-workflow/agent-end" }`](#persistence-type-sha256-babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7) | +| `event:tool-workflow/agent-start` | event | `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` | [`{ type: "tool-workflow/agent-start" }`](#persistence-type-sha256-5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627) | +| `event:tool-workflow/run-end` | event | `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` | [`{ type: "tool-workflow/run-end" }`](#persistence-type-sha256-42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f) | +| `event:tool-workflow/run-start` | event | `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` | [`{ type: "tool-workflow/run-start" }`](#persistence-type-sha256-c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058) | +| `event:tool/call` | event | `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` | [`{ type: "tool/call" }`](#persistence-type-sha256-3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48) | +| `event:tool/ptc-dispatch` | event | `100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163` | [`{ type: "tool/ptc-dispatch" }`](#persistence-type-sha256-100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163) | +| `event:tool/ptc-dispatch-start` | event | `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` | [`{ type: "tool/ptc-dispatch-start" }`](#persistence-type-sha256-ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93) | +| `event:tool/result` | event | `7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397` | [`{ type: "tool/result" }`](#persistence-type-sha256-7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397) | +| `event:turn/end` | event | `0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce` | [`{ type: "turn/end" }`](#persistence-type-sha256-0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce) | +| `event:turn/start` | event | `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` | [`{ type: "turn/start" }`](#persistence-type-sha256-aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8) | +| `event:user/message` | event | `3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761` | [`{ type: "user/message" }`](#persistence-type-sha256-3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761) | +| `event:web/deepseek-search-llm-request` | event | `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` | [`{ type: "web/deepseek-search-llm-request" }`](#persistence-type-sha256-cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331) | +| `event:workspace/changes` | event | `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | [`{ type: "workspace/changes" }`](#persistence-type-sha256-e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72) | ## 事件信封 @@ -95,6 +96,7 @@ export type SessionEventType = keyof SessionEventMap */ export type SurfaceEventType = | 'system/message' + | 'developer/message' | 'user/message' | 'assistant/message' | 'tool/result' @@ -155,7 +157,7 @@ export type SessionEvent = { }[T] ``` -来源:[`packages/core/session/src/types.ts:409`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:417`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:439`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:470`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:431`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:439`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:462`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:493`](../packages/core/session/src/types.ts) ## 事件 @@ -265,7 +267,7 @@ export type SessionEvent = { } ``` -来源:[`packages/interaction/user-approval/src/index.ts:33`](../packages/interaction/user-approval/src/index.ts) +来源:[`packages/interaction/user-approval/src/index.ts:40`](../packages/interaction/user-approval/src/index.ts) ### `assistant/*` @@ -282,7 +284,7 @@ export type SessionEvent = { 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[] } ``` -来源:[`packages/core/session/src/types.ts:335`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) @@ -312,7 +314,7 @@ export type SessionEvent = { 类型:[TokenUsage](subsystems/llm-streaming.zh.md) -来源:[`packages/core/session/src/types.ts:321`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) ### `command/*` @@ -483,6 +485,25 @@ export type SessionEvent = { 来源:[`packages/deliverables/tool-present/src/types.ts:15`](../packages/deliverables/tool-present/src/types.ts) +### `developer/*` + + + +#### `developer/message` — surface + +```ts persistence-catalog +/** An incremental agent session change admitted at the named turn and step. */ +'developer/message': { + turn: number + step: number + message: DeveloperMessage + /** Earlier request/header defining every tool addition; required exactly when additions are present. */ + headerSeq?: SessionSeq +} +``` + +来源:[`packages/core/session/src/types.ts:311`](../packages/core/session/src/types.ts) + ### `feedback/*` @@ -678,7 +699,7 @@ export type SessionEvent = { 'plan/mode': { active: boolean } ``` -来源:[`packages/plan/plan-mode/src/index.ts:47`](../packages/plan/plan-mode/src/index.ts) +来源:[`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts) ### `request/*` @@ -696,7 +717,7 @@ export type SessionEvent = { 'request/context': RequestContext ``` -来源:[`packages/core/session/src/types.ts:382`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:402`](../packages/core/session/src/types.ts) @@ -715,7 +736,7 @@ export type SessionEvent = { } ``` -来源:[`packages/core/session/src/types.ts:370`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:390`](../packages/core/session/src/types.ts) ### `sandbox/*` @@ -766,19 +787,21 @@ export type SessionEvent = { ```ts persistence-catalog /** - * Marks the end of a constructor seed. Events before it have smaller seq - * values and came from the seed (resume, fork, or replay); this lifecycle - * produced none of them. This log-only event is the durable projection of - * {@link Session.firstLiveSeq}. + * Separates inherited or restored history from later lifecycle-owned work. + * This log-only marker need not be at {@link Session.firstLiveSeq}: a fork + * seed can already contain its tagged marker and child-owned synthetic + * closers before construction. * * A fresh fork child owns one `{ inherited: true }` marker at its exact * inherited-prefix cut, even when that prefix ends in an ancestor marker. - * The last tagged marker is the current Session's cut; untagged markers keep - * ordinary restore and replay lifecycle boundaries. + * `buildForkSeed` appends that marker before any synthetic closers; the + * `Session` constructor supplies it when given only the inherited prefix. + * The last tagged marker is the current Session's cut; untagged markers + * keep ordinary restore and replay lifecycle boundaries. * - * `Session`'s constructor is the only legitimate writer. The invariant - * companion deliberately constrains nothing here, so a plugin appending one - * would silently classify every live bracket before it as seed history. + * Only the `Session` constructor and `buildForkSeed` may create this marker. + * The invariant companion deliberately constrains nothing here, so a plugin + * appending one would silently classify every live bracket before it as seed history. * * An owner of a standalone open/close bracket (`compaction/start` … * `compaction/end`) reads it because seed history and live work are otherwise @@ -790,7 +813,7 @@ export type SessionEvent = { 'session/end-seed': { inherited?: true } ``` -来源:[`packages/core/session/src/types.ts:405`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:427`](../packages/core/session/src/types.ts) @@ -819,7 +842,7 @@ export type SessionEvent = { 类型:[SessionTitleLlmRequestEventData](subsystems/session-title.zh.md) -来源:[`packages/session/session-title-llm/src/index.ts:45`](../packages/session/session-title-llm/src/index.ts) +来源:[`packages/session/session-title-llm/src/index.ts:52`](../packages/session/session-title-llm/src/index.ts) ### `session-log-deepseek/*` @@ -852,7 +875,7 @@ export type SessionEvent = { 'step/end': { turn: number; step: number } ``` -来源:[`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:301`](../packages/core/session/src/types.ts) @@ -863,7 +886,7 @@ export type SessionEvent = { 'step/start': { turn: number; step: number } ``` -来源:[`packages/core/session/src/types.ts:287`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:299`](../packages/core/session/src/types.ts) ### `subagent/*` @@ -939,7 +962,7 @@ export type SessionEvent = { 'system/message': { turn: number; step: number; message: SystemMessage } ``` -来源:[`packages/core/session/src/types.ts:310`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:330`](../packages/core/session/src/types.ts) ### `team/*` @@ -1032,7 +1055,7 @@ export type SessionEvent = { 类型:[ToolCallId](subsystems/core.zh.md) -来源:[`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:361`](../packages/core/session/src/types.ts) @@ -1106,14 +1129,14 @@ export type SessionEvent = { message: ToolResultMessage /** * Optional failure identity and raw user-facing reason, outside model content; - * allowed only when the tool-result block has `isError: true`. + * allowed only when the message has `isError: true`. */ error?: { name: string; code: string; reason?: string } meta?: JsonValue } ``` -来源:[`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:375`](../packages/core/session/src/types.ts) ### `tool-workflow/*` @@ -1193,7 +1216,7 @@ export type SessionEvent = { 类型:[TurnEndReason](subsystems/session.zh.md) -来源:[`packages/core/session/src/types.ts:285`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:297`](../packages/core/session/src/types.ts) @@ -1209,7 +1232,7 @@ export type SessionEvent = { 'turn/start': { turn: number } ``` -来源:[`packages/core/session/src/types.ts:276`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:288`](../packages/core/session/src/types.ts) ### `user/*` @@ -1228,7 +1251,7 @@ export type SessionEvent = { 'user/message': UserMessage ``` -来源:[`packages/core/session/src/types.ts:297`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:309`](../packages/core/session/src/types.ts) ### `web/*` @@ -1264,39 +1287,7 @@ export type SessionEvent = { 每个类型定义仅列出一次。引用保留共享和递归关系;定义旁的摘要涵盖其完整可达结构。源码名称和位置标识声明来源,但不参与摘要计算。 - - -### `0` - -SHA-256: `93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35` - -`0` - - - -### `1` - -SHA-256: `f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d` - -`1` - - - -### `2` - -SHA-256: `a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80` - -`2` - - - -### `3` - -SHA-256: `137ac60e26bcb192210d9a32a704b73b0924ed34019323defa1b787be95bd45e` - -`3` - - + ### `"aborted"` @@ -1304,7 +1295,7 @@ SHA-256: `1e0b0b66b6f0c53fc72e52289d06b4708d776f1ca9df4c86a22bff621d403cf0` `"aborted"` - + ### `"active"` @@ -1312,7 +1303,7 @@ SHA-256: `c8e6f48878cc2a2f0dc59682280d81f407943fb503f32c64bf9ff3d9393c3eff` `"active"` - + ### `"after"` @@ -1320,7 +1311,7 @@ SHA-256: `5b232a9b9bfcc0fc6794dab7865bcf203a65785c5de5aa647a51228bff628413` `"after"` - + ### `"agent-instructions"` @@ -1328,7 +1319,7 @@ SHA-256: `fbd2c74b346a1595b376139c587fadd23e4a21acc9c0abce342975b6cfc60986` `"agent-instructions"` - + ### `"agent-message"` @@ -1336,7 +1327,7 @@ SHA-256: `82470020b5bfcb1a843e2aa05602af7d37df99e82d01f015c7c589ba054fd89d` `"agent-message"` - + ### `"agent-preset/selected"` @@ -1344,7 +1335,7 @@ SHA-256: `557e148d30b79ee48645850832b30c717d7c3b64641deb5d6133b8b4e91ee0b8` `"agent-preset/selected"` - + ### `"agent/inbox/spliced"` @@ -1352,7 +1343,7 @@ SHA-256: `829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809` `"agent/inbox/spliced"` - + ### `"allowed-once"` @@ -1360,7 +1351,7 @@ SHA-256: `811229eedcec57979dbadca7dbea832a59f8580cff30cb217fca5e2da16314bd` `"allowed-once"` - + ### `"always"` @@ -1368,7 +1359,7 @@ SHA-256: `142c37d302aa22a0a57915b5255939d3ca91c1811ca13fddcf84cf76ea00758a` `"always"` - + ### `"append"` @@ -1376,7 +1367,7 @@ SHA-256: `e438a9d4fb883b3e4a8d9fc8913aa1550ed50eb384bfbf943100a5605b537498` `"append"` - + ### `"approval/asked"` @@ -1384,7 +1375,7 @@ SHA-256: `cd186c309e2bef305705e1d324139240f5e681f4f6a957d6a25b0225f65560df` `"approval/asked"` - + ### `"approval/decided"` @@ -1392,7 +1383,7 @@ SHA-256: `378f90f9f6022a0991928a1eaf7991094ea1920fe89a9248358a1da106e1a970` `"approval/decided"` - + ### `"approval/policy"` @@ -1400,7 +1391,7 @@ SHA-256: `36d6a9a871d949ea4f3edd919d81d66aa69218bebef38899d2a1282c39420a1f` `"approval/policy"` - + ### `"ask"` @@ -1408,7 +1399,7 @@ SHA-256: `9e07693fd7cd9babe0688c22c986e4d519ae1c0e40eeea13b2dc583bed2abc86` `"ask"` - + ### `"assistant"` @@ -1416,7 +1407,7 @@ SHA-256: `95c0e88fcf0bafb2087f912ad9e2369de6ae6530cc0c4c2772c96205b57f7f60` `"assistant"` - + ### `"assistant/attempt"` @@ -1424,7 +1415,7 @@ SHA-256: `e95f957154b2b1b58692af53d4131180b6dd19e2264869f876dbaa959991494e` `"assistant/attempt"` - + ### `"assistant/message"` @@ -1432,7 +1423,7 @@ SHA-256: `6ab45ac76839722df912f3ba50f1c6b41f2d614bde11f1aabfae04117ccdc80d` `"assistant/message"` - + ### `"at"` @@ -1440,7 +1431,7 @@ SHA-256: `17aae616ef020b8b9f011ec398ec935450fb06d3e2a0722c456f63aeaf5ff728` `"at"` - + ### `"block"` @@ -1448,7 +1439,7 @@ SHA-256: `1e346446e183ee76f48d7994c97ecb302bddc682abb60b8a10ea0bb26223a69c` `"block"` - + ### `"block-end"` @@ -1456,7 +1447,7 @@ SHA-256: `eefbea819caeeea91ccb02dfafc16c68dd7f961cf9c1b2be25a2084509cf5c5a` `"block-end"` - + ### `"block-start"` @@ -1464,7 +1455,7 @@ SHA-256: `cbca49bde16b656d5b8fbe4a8a507769f7b594c6287782b809c03814941bc5e3` `"block-start"` - + ### `"blocked"` @@ -1472,15 +1463,7 @@ SHA-256: `254dce209e735f9cb6f6b7aec0354712b1611759ec02af4d35a96f2081e666f6` `"blocked"` - - -### `boolean` - -SHA-256: `aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877` - -`boolean` - - + ### `"canceled"` @@ -1488,7 +1471,7 @@ SHA-256: `d4e4d575abeb4b72d616dc65c17ac0eaa943cc135609395044c38d5afcb10e31` `"canceled"` - + ### `"cancelled"` @@ -1496,7 +1479,7 @@ SHA-256: `2142e391b9ccb60d487afcf373ce74db98d952f69e8289eddb352a7e16e996c5` `"cancelled"` - + ### `"catalog"` @@ -1504,7 +1487,7 @@ SHA-256: `aec150797b655c5f15ebb7a501454b0c208fbaccec9ace49d7de2171fc02f47d` `"catalog"` - + ### `"change"` @@ -1512,7 +1495,7 @@ SHA-256: `f789af5ab844827eb5a4f357c0afae1eeed108c6c22d8ca1a56e586b349a7c85` `"change"` - + ### `"chunk"` @@ -1520,7 +1503,7 @@ SHA-256: `14230f9b8b5797bb7e8c621fa636531cfbde2ffba1ef5f1fd058216ff21952a0` `"chunk"` - + ### `"claude-code"` @@ -1528,7 +1511,7 @@ SHA-256: `aff60ef947c18b012644852bdd0d5bfe72065e061dd563787c76c646b4a10f6b` `"claude-code"` - + ### `"clear"` @@ -1536,7 +1519,7 @@ SHA-256: `e7e154d47d5fbc5366330fb4dade1f108c6dfe4335044d21ded14b7bf1dce084` `"clear"` - + ### `"codex"` @@ -1544,7 +1527,7 @@ SHA-256: `15495614ccfa9cbdeefb0ec2abd76406435f4c6ff3dae42acae8e09ef42025c9` `"codex"` - + ### `"command/done"` @@ -1552,7 +1535,7 @@ SHA-256: `8cdd3fdd295cee53035de16a1b23411716f75e9f994fe9510cac5d7fef605c76` `"command/done"` - + ### `"command/run"` @@ -1560,7 +1543,15 @@ SHA-256: `f1996af2602e6f62b5ab179ca5c4af00d8753938b74cc6ef102de09e99e74a7e` `"command/run"` - + + +### `"compact-checkpoint"` + +SHA-256: `6b23ed9ce1b397e602788dbe033693bf97642a69e23fcab1cc45bf6f13b6d619` + +`"compact-checkpoint"` + + ### `"compaction/end"` @@ -1568,7 +1559,7 @@ SHA-256: `1986c2664009c99155e44795676c887fa67f7c55cd2d5e6b648ff763e0ab033a` `"compaction/end"` - + ### `"compaction/prune"` @@ -1576,7 +1567,7 @@ SHA-256: `10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe` `"compaction/prune"` - + ### `"compaction/start"` @@ -1584,7 +1575,7 @@ SHA-256: `e2d0367e5716bc188435e51718ebff8ce873190625fa93b1c5331102d98758fa` `"compaction/start"` - + ### `"compaction/summary"` @@ -1592,7 +1583,7 @@ SHA-256: `ef4f00923b9edbae15c7ef05320280bf61147ca17146cf59690359bfd5e5da45` `"compaction/summary"` - + ### `"complete"` @@ -1600,7 +1591,7 @@ SHA-256: `d9196086e41e4dd5c2ce87f5c25529c8112a1731d258cf0728747d41a9ee3241` `"complete"` - + ### `"completed"` @@ -1608,7 +1599,7 @@ SHA-256: `1ebc6f9ff3aa9e3a38f8695f49bacdab1f8b7a3832741853ca46f40af56ccd01` `"completed"` - + ### `"continuable"` @@ -1616,7 +1607,15 @@ SHA-256: `e5d3828df1ec3e2a66879de0659e0f4866d9cfffc00825ee731a66f8a0c03d98` `"continuable"` - + + +### `"cordis-host-runner"` + +SHA-256: `c5687b1313206a6ff334066047b6a0681611467dc4df8c5a8e71d0b6df39311f` + +`"cordis-host-runner"` + + ### `"create"` @@ -1624,7 +1623,7 @@ SHA-256: `7624ca28c61ca0eaa4f015140f3cea6e0c16cce2f2960fab5f531203d253903e` `"create"` - + ### `"danger-full-access"` @@ -1632,7 +1631,7 @@ SHA-256: `18fce9540bb20897a66275499faee6b8296c97e9901fa1ff45a191772448ad1a` `"danger-full-access"` - + ### `"delegation"` @@ -1640,7 +1639,7 @@ SHA-256: `76632533f67879dcb346fcae640540dbc89b2472b0bce88c59f7e48fc5c0e668` `"delegation"` - + ### `"delete"` @@ -1648,7 +1647,7 @@ SHA-256: `d0fbb0ca1bbba059830826f33f801da1aced35a2504376d61e020bdfec8d50c0` `"delete"` - + ### `"deleted"` @@ -1656,7 +1655,7 @@ SHA-256: `e7e8f1318170b8284f16ab45a557afd4675c96071c0f2a456636481dab20b427` `"deleted"` - + ### `"deliverables/presented"` @@ -1664,7 +1663,23 @@ SHA-256: `1a2718b00937b236a0d0910ef5dab2f9f8b65e4bde410cc21f15fbbf29f584d3` `"deliverables/presented"` - + + +### `"developer"` + +SHA-256: `589d0d91239681f89ee485459dc8c2f73ea47183b5534289d966637024a2c35d` + +`"developer"` + + + +### `"developer/message"` + +SHA-256: `1379f0b72275994d20f1ddca2d60a96ab16ec80397ca9f1af21bdc67ba5c269c` + +`"developer/message"` + + ### `"dispatch"` @@ -1672,7 +1687,7 @@ SHA-256: `26c879bdd130e8b8683a6ce588414fad2244783d6573ca399fa0de184a2b0bb1` `"dispatch"` - + ### `"disposed"` @@ -1680,7 +1695,15 @@ SHA-256: `b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751` `"disposed"` - + + +### `"dsh-session-title-llm"` + +SHA-256: `23af3759678a30de1d11d946772da8c051c63caa67997c5da05d30d7a9fe8a97` + +`"dsh-session-title-llm"` + + ### `"edit"` @@ -1688,7 +1711,7 @@ SHA-256: `ad22a5ca5bbaab2e1440779cd3648e85ddfc6f73b5207394eda699555cf31430` `"edit"` - + ### `"error"` @@ -1696,169 +1719,3693 @@ SHA-256: `a2be0f0cb59f0d4a06557d45847d1938aced238baa77a6da416e590b8b958553` `"error"` - + -### `event:agent-preset/selected` +### `"every"` -SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` +SHA-256: `e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87` + +`"every"` + + + +### `"failed"` + +SHA-256: `b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420` + +`"failed"` + + + +### `"fallback"` + +SHA-256: `d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c` + +`"fallback"` + + + +### `"feedback/message-delete"` + +SHA-256: `44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e` + +`"feedback/message-delete"` + + + +### `"feedback/message-put"` + +SHA-256: `6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8` + +`"feedback/message-put"` + + + +### `"feedback/record"` + +SHA-256: `c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954` + +`"feedback/record"` + + + +### `"file"` + +SHA-256: `277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9` + +`"file"` + + + +### `"finish"` + +SHA-256: `bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd` + +`"finish"` + + + +### `"fork"` + +SHA-256: `2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863` + +`"fork"` + + + +### `"forked"` + +SHA-256: `b2245a906e13aa94f2d3cc6cf7b04cfa0267f7b7f4d468de1b00b1a314e54626` + +`"forked"` + + + +### `"fresh"` + +SHA-256: `dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d` + +`"fresh"` + + + +### `"goal"` + +SHA-256: `b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602` + +`"goal"` + + + +### `"goal/change"` + +SHA-256: `237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163` + +`"goal/change"` + + + +### `"hook"` + +SHA-256: `dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc` + +`"hook"` + + + +### `"hook/invoked"` + +SHA-256: `b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611` + +`"hook/invoked"` + + + +### `"hook/result"` + +SHA-256: `a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2` + +`"hook/result"` + + + +### `"hooks-claude-code"` + +SHA-256: `a9059a81430b320792bbb7c2ee1f8f6c77ff71e40ee44c18aec72e157c522694` + +`"hooks-claude-code"` + + + +### `"hooks-codex"` + +SHA-256: `bb94f3217aa56c8876bbff0b8460d6a73cbead545659abb29e76cd0cf2cb92d6` + +`"hooks-codex"` + + + +### `"image"` + +SHA-256: `fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0` + +`"image"` + + + +### `"image/gif"` + +SHA-256: `de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048` + +`"image/gif"` + + + +### `"image/jpeg"` + +SHA-256: `3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004` + +`"image/jpeg"` + + + +### `"image/offload"` + +SHA-256: `9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49` + +`"image/offload"` + + + +### `"image/png"` + +SHA-256: `58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0` + +`"image/png"` + + + +### `"image/webp"` + +SHA-256: `ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8` + +`"image/webp"` + + + + + + + +### `"in-history"` + +SHA-256: `f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5` + +来源:[`packages/llm/llm/src/types.ts:397`](../packages/llm/llm/src/types.ts) + +`"in-history"` + + + +### `"in_progress"` + +SHA-256: `94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378` + +`"in_progress"` + + + +### `"initial"` + +SHA-256: `e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c` + +`"initial"` + + + +### `"instruction-following"` + +SHA-256: `e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486` + +`"instruction-following"` + + + +### `"instructions"` + +SHA-256: `fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5` + +`"instructions"` + + + +### `"interrupted"` + +SHA-256: `69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199` + +`"interrupted"` + + + +### `"legacy"` + +SHA-256: `ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc` + +`"legacy"` + + + +### `"llm/retry"` + +SHA-256: `611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d` + +`"llm/retry"` + + + +### `"llm/retry-started"` + +SHA-256: `4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964` + +`"llm/retry-started"` + + + +### `"max-tokens"` + +SHA-256: `68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe` + +`"max-tokens"` + + + +### `"model"` + +SHA-256: `2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e` + +`"model"` + + + +### `"model-selection"` + +SHA-256: `9ac52f0f84fec2eb9f71c2937e497d759db5ca0da4836d93a679d113684141f2` + +`"model-selection"` + + + +### `"model/selection"` + +SHA-256: `1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2` + +`"model/selection"` + + + +### `"negative"` + +SHA-256: `b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5` + +`"negative"` + + + +### `"never"` + +SHA-256: `1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b` + +`"never"` + + + +### `"next-step"` + +SHA-256: `3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693` + +`"next-step"` + + + +### `"next-turn"` + +SHA-256: `62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd` + +`"next-turn"` + + + +### `"normal"` + +SHA-256: `3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79` + +`"normal"` + + + +### `"notice"` + +SHA-256: `e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367` + +`"notice"` + + + +### `"one-shot"` + +SHA-256: `d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2` + +`"one-shot"` + + + +### `"other"` + +SHA-256: `9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4` + +`"other"` + + + +### `"parent"` + +SHA-256: `e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732` + +`"parent"` + + + +### `"pause"` + +SHA-256: `1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721` + +`"pause"` + + + +### `"paused"` + +SHA-256: `c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943` + +`"paused"` + + + +### `"pending"` + +SHA-256: `234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85` + +`"pending"` + + + +### `"permission/preset"` + +SHA-256: `ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649` + +`"permission/preset"` + + + +### `"plan-mode"` + +SHA-256: `0fe52387f65052702ed9d7cd59db826468936595d1b3eec207e7a823adc719db` + +`"plan-mode"` + + + +### `"plan/mode"` + +SHA-256: `f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9` + +`"plan/mode"` + + + +### `"positive"` + +SHA-256: `df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528` + +`"positive"` + + + +### `"product-interaction"` + +SHA-256: `0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23` + +`"product-interaction"` + + + +### `"provider"` + +SHA-256: `e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a` + +`"provider"` + + + +### `"provisioning"` + +SHA-256: `871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62` + +`"provisioning"` + + + +### `"ptc-mode"` + +SHA-256: `4edec1b770e8ec4ce1220bf42edc5ac46713a1b48d4caa778dcfc98bad1f28a3` + +`"ptc-mode"` + + + +### `"read-only"` + +SHA-256: `12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42` + +`"read-only"` + + + +### `"reasoning"` + +SHA-256: `3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c` + +`"reasoning"` + + + +### `"reasoning-chunks"` + +SHA-256: `688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8` + +`"reasoning-chunks"` + + + +### `"reasoning-delta"` + +SHA-256: `6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6` + +`"reasoning-delta"` + + + +### `"recall"` + +SHA-256: `383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f` + +`"recall"` + + + +### `"rejected"` + +SHA-256: `fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018` + +`"rejected"` + + + +### `"relay"` + +SHA-256: `16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e` + +`"relay"` + + + +### `"remove"` + +SHA-256: `7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc` + +`"remove"` + + + +### `"repeat-tool-reminder"` + +SHA-256: `1f1385dbc3e875c021e387c7096d671d606f22daec51b25c80348735b6bbfa10` + +`"repeat-tool-reminder"` + + + +### `"replace"` + +SHA-256: `f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8` + +`"replace"` + + + +### `"request/context"` + +SHA-256: `70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2` + +`"request/context"` + + + +### `"request/header"` + +SHA-256: `3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e` + +`"request/header"` + + + +### `"resource-cost"` + +SHA-256: `5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75` + +`"resource-cost"` + + + +### `"resume"` + +SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66` + +`"resume"` + + + +### `"runtime-context"` + +SHA-256: `24b10f7cdae64928f89c49afc2eca0af9eb4a2f135e16f3416e6b8461fef1748` + +`"runtime-context"` + + + +### `"sandbox/mode"` + +SHA-256: `ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2` + +`"sandbox/mode"` + + + +### `"schedule"` + +SHA-256: `d9edf1862e4471d6ad8a106a3f4160e0643874368707d50ecd8e27e5ee7a2567` + +`"schedule"` + + + +### `"schedule/change"` + +SHA-256: `0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d` + +`"schedule/change"` + + + +### `"security-privacy-permission"` + +SHA-256: `07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7` + +`"security-privacy-permission"` + + + +### `"series"` + +SHA-256: `4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f` + +`"series"` + + + +### `"service-stability"` + +SHA-256: `7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732` + +`"service-stability"` + + + +### `"session"` + +SHA-256: `e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828` + +`"session"` + + + +### `"session-log-deepseek/delivery-accepted"` + +SHA-256: `47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b` + +`"session-log-deepseek/delivery-accepted"` + + + +### `"session-reference"` + +SHA-256: `7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71` + +`"session-reference"` + + + +### `"session/end-seed"` + +SHA-256: `1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330` + +`"session/end-seed"` + + + +### `"session/title"` + +SHA-256: `7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50` + +`"session/title"` + + + +### `"session/title-llm-request"` + +SHA-256: `587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e` + +`"session/title-llm-request"` + + + +### `"set"` + +SHA-256: `b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b` + +`"set"` + + + +### `"skill-catalog"` + +SHA-256: `6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3` + +`"skill-catalog"` + + + +### `"skill-invocation"` + +SHA-256: `1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509` + +`"skill-invocation"` + + + +### `"snapshot"` + +SHA-256: `6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912` + +`"snapshot"` + + + +### `"step/end"` + +SHA-256: `c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70` + +`"step/end"` + + + +### `"step/start"` + +SHA-256: `2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d` + +`"step/start"` + + + +### `"stop"` + +SHA-256: `57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90` + +`"stop"` + + + +### `"subagent"` + +SHA-256: `aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6` + +`"subagent"` + + + +### `"subagent-settled"` + +SHA-256: `bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a` + +`"subagent-settled"` + + + +### `"subagent/catalog"` + +SHA-256: `44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2` + +`"subagent/catalog"` + + + +### `"subagent/descriptor"` + +SHA-256: `5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647` + +`"subagent/descriptor"` + + + +### `"subagent/model-selection-policy"` + +SHA-256: `0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da` + +`"subagent/model-selection-policy"` + + + +### `"success"` + +SHA-256: `511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7` + +`"success"` + + + +### `"system"` + +SHA-256: `8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3` + +`"system"` + + + +### `"system-prompt"` + +SHA-256: `09655b34d7f3cf1e9005974de2357de2d4a60deea165d16dac1eadaa6ec539a8` + +`"system-prompt"` + + + +### `"system/message"` + +SHA-256: `1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7` + +`"system/message"` + + + +### `"task-result"` + +SHA-256: `f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c` + +`"task-result"` + + + +### `"team-message"` + +SHA-256: `2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c` + +`"team-message"` + + + +### `"team/member"` + +SHA-256: `18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0` + +`"team/member"` + + + +### `"team/message/delivered"` + +SHA-256: `a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57` + +`"team/message/delivered"` + + + +### `"team/message/queued"` + +SHA-256: `4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159` + +`"team/message/queued"` + + + +### `"team/task"` + +SHA-256: `b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b` + +`"team/task"` + + + +### `"text"` + +SHA-256: `4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d` + +`"text"` + + + +### `"text-chunks"` + +SHA-256: `f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3` + +`"text-chunks"` + + + +### `"text-delta"` + +SHA-256: `5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563` + +`"text-delta"` + + + +### `"time-context"` + +SHA-256: `8067b0d232c350f189738e60ee3c9939d46ca3b32b45db5525237b077893f649` + +`"time-context"` + + + +### `"tmux-context"` + +SHA-256: `78a9be340090b735a39980e7222ce730c972fbcf1de7c9e0aef2125884b7caee` + +`"tmux-context"` + + + +### `"todo/write"` + +SHA-256: `af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7` + +`"todo/write"` + + + +### `"tool"` + +SHA-256: `a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847` + +`"tool"` + + + +### `"tool-addition"` + +SHA-256: `85f9b505b7bdff1f61845c4cea8f36fd0fde1b62facbe87d8924d1d27e616f3a` + +`"tool-addition"` + + + +### `"tool-call"` + +SHA-256: `1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7` + +`"tool-call"` + + + +### `"tool-call-chunks"` + +SHA-256: `616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5` + +`"tool-call-chunks"` + + + +### `"tool-call-delta"` + +SHA-256: `9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267` + +`"tool-call-delta"` + + + +### `"tool-calls"` + +SHA-256: `6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b` + +`"tool-calls"` + + + +### `"tool-goal"` + +SHA-256: `2f3f201c8846e19c20bb75c02280e3d4eb3c57509e4715f0c0a4d1d4f91a7a06` + +`"tool-goal"` + + + +### `"tool-jobs"` + +SHA-256: `99e7e7d7fed55ae6a3a648b35192f16ab1248ddcb0179a0e275128ac1487d7c7` + +`"tool-jobs"` + + + +### `"tool-registry"` + +SHA-256: `a720757f704a2512e9d2f20da4a093e582472176236a75ab8b8eb7aaff17d85a` + +`"tool-registry"` + + + +### `"tool-removal"` + +SHA-256: `83d6916021eede8f2d83a1872716caa1efdec39a3681890996c55147187fdd12` + +`"tool-removal"` + + + +### `"tool-workflow/agent-end"` + +SHA-256: `5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e` + +`"tool-workflow/agent-end"` + + + +### `"tool-workflow/agent-start"` + +SHA-256: `ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8` + +`"tool-workflow/agent-start"` + + + +### `"tool-workflow/run-end"` + +SHA-256: `fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd` + +`"tool-workflow/run-end"` + + + +### `"tool-workflow/run-start"` + +SHA-256: `cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670` + +`"tool-workflow/run-start"` + + + +### `"tool/call"` + +SHA-256: `c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92` + +`"tool/call"` + + + +### `"tool/ptc-dispatch"` + +SHA-256: `fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973` + +`"tool/ptc-dispatch"` + + + +### `"tool/ptc-dispatch-start"` + +SHA-256: `2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456` + +`"tool/ptc-dispatch-start"` + + + +### `"tool/result"` + +SHA-256: `570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833` + +`"tool/result"` + + + +### `"turn/end"` + +SHA-256: `4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03` + +`"turn/end"` + + + +### `"turn/start"` + +SHA-256: `0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f` + +`"turn/start"` + + + +### `"unavailable"` + +SHA-256: `2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c` + +`"unavailable"` + + + +### `"usage"` + +SHA-256: `0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9` + +`"usage"` + + + +### `"user"` + +SHA-256: `68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573` + +`"user"` + + + +### `"user-approval"` + +SHA-256: `f68c335306535a001127dae6685ece493a0ee7f4e2a851197b6054d8a9ff7394` + +`"user-approval"` + + + +### `"user/message"` + +SHA-256: `de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f` + +`"user/message"` + + + +### `"web/deepseek-search-llm-request"` + +SHA-256: `6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675` + +`"web/deepseek-search-llm-request"` + + + +### `"web_search"` + +SHA-256: `935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682` + +`"web_search"` + + + +### `"web_search_20250305"` + +SHA-256: `0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e` + +`"web_search_20250305"` + + + +### `"webhook"` + +SHA-256: `db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0` + +`"webhook"` + + + +### `"workspace-write"` + +SHA-256: `a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa` + +`"workspace-write"` + + + +### `"workspace/changes"` + +SHA-256: `8e8155594e07812356b67d732196dda894b0f9c91a5969d51612cf490b0a016d` + +`"workspace/changes"` + + + +### `0` + +SHA-256: `93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35` + +`0` + + + +### `1` + +SHA-256: `f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d` + +`1` + + + +### `2` + +SHA-256: `a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80` + +`2` + + + +### `4` + +SHA-256: `af6e173f7be819bcd0a5c8d77918649c10ce761d8a184ff472f2e01ce64eb2e0` + +`4` + + + + + + + +### `AfterScheduleRecord` + +SHA-256: `27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe` + +来源:[`packages/schedule/schedule/src/types.ts:13`](../packages/schedule/schedule/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:agent-preset/selected.data`](#persistence-type-eventagent-presetselecteddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"agent-preset/selected"` | +| `afterSeconds` | 必需 | `number` | +| `id` | 必需 | `string` | +| `kind` | 必需 | `"after"` | +| `prompt` | 必需 | `string` | +| `scheduledAt` | 必需 | `string` | - + -### `event:agent-preset/selected.data` + -SHA-256: `6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406` + -来源:[`packages/preset/agent-presets/src/session.ts:28`](../packages/preset/agent-presets/src/session.ts) +### `AgentInstructionChange` + +SHA-256: `83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239` + +来源:[`packages/context/agent-instructions/src/render.ts:47`](../packages/context/agent-instructions/src/render.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `agentPreset` | 必需 | `string` | +| `action` | 必需 | [`union (3 variants)`](#persistence-type-sha256-904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd) | +| `digest` | 可选 | `string` | +| `path` | 必需 | `string` | +| `scope` | 必需 | `string` | - + -### `event:agent/inbox/spliced` - -SHA-256: `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:agent/inbox/spliced.data`](#persistence-type-eventagentinboxspliceddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"agent/inbox/spliced"` | - - - -### `event:agent/inbox/spliced.data` - -SHA-256: `a6a195c1b4a906d953d24ab5864c9f1881d545460e080a51144adfc9cb058cfe` - -来源:[`packages/core/agent/src/types.ts:87`](../packages/core/agent/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `inserted` | 必需 | [`event:agent/inbox/spliced.data.inserted`](#persistence-type-eventagentinboxspliceddatainserted) | -| `outcome` | 可选 | `"canceled"` | -| `removedCount` | 可选 | `number` | -| `start` | 必需 | `number` | -| `target` | 必需 | [`packages/core/agent/src/types.ts#InboxTarget`](#persistence-type-packagescoreagentsrctypestsinboxtarget) | - - - -### `event:agent/inbox/spliced.data.inserted` - -SHA-256: `300341f890f7b9506a1749fff4fa5239d16ea1c63ff6b15851acb03c20f3b48d` - -[`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage) 的数组。 - - - -### `event:agent/inbox/spliced.data.inserted[0].content` - -SHA-256: `bb72d86bc9ef0b3908bfa57ef98ccccae24d67d945c9f6869ca3cb8577889e75` - -[`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock) 的数组。 - - - -### `event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions` - -SHA-256: `0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef` - -来源:[`packages/attachment/attachment/src/types.ts:28`](../packages/attachment/attachment/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `height` | 必需 | `number` | -| `width` | 必需 | `number` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[0]` - -SHA-256: `ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05` - -来源:[`packages/core/session/src/types.ts:189`](../packages/core/session/src/types.ts) · [`packages/interaction/commands/src/types.ts:75`](../packages/interaction/commands/src/types.ts) · [`packages/interaction/commands/src/types.ts:79`](../packages/interaction/commands/src/types.ts) · [`packages/llm/llm/src/message.ts:103`](../packages/llm/llm/src/message.ts) · [`packages/session/session-title/src/types.ts:35`](../packages/session/session-title/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"user"` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[1]` - -SHA-256: `0ddab4577db37a3e0d9e3a91761735c8ef6f5629d526ab8ecaeeea19c097c8f8` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[11]` - -SHA-256: `6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7` - -来源:[`packages/api/session-controller/src/types.ts:381`](../packages/api/session-controller/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `clientTimeZone` | 可选 | `string` | -| `kind` | 必需 | `"user"` | -| `rpcId` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[15].references` - -SHA-256: `df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18` - -[`event:agent/inbox/spliced.data.inserted[0].source[15].references[0]`](#persistence-type-eventagentinboxspliceddatainserted0source15references0) 的数组。 - - - -### `event:agent/inbox/spliced.data.inserted[0].source[15].references[0]` - -SHA-256: `4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4` - -来源:[`packages/context/session-reference/src/types.ts:18`](../packages/context/session-reference/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `capturedFormatVersion` | 可选 | `number` | -| `capturedThroughSeq` | 必需 | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | -| `compacted` | 必需 | `boolean` | -| `inputIndex` | 必需 | `number` | -| `label` | 必需 | `string` | -| `omittedBytes` | 必需 | `number` | -| `omittedMessages` | 必需 | `number` | -| `originalMessages` | 必需 | `number` | -| `retainedMessages` | 必需 | `number` | -| `sessionId` | 必需 | `string` | -| `truncated` | 必需 | `boolean` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[16].changes` +### `AgentInstructionChange[]` SHA-256: `2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee` -[`packages/context/agent-instructions/src/render.ts#AgentInstructionChange`](#persistence-type-packagescontextagent-instructionssrcrendertsagentinstructionchange) 的数组。 +[`AgentInstructionChange`](#persistence-type-sha256-83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239) 的数组。 - + -### `event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action` + + + + +### `AgentInstructionSource` + +SHA-256: `6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590` + +来源:[`packages/context/agent-instructions/src/state.ts:37`](../packages/context/agent-instructions/src/state.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `baseline` | 可选 | `true` | +| `baselineIdentity` | 可选 | `string` | +| `changes` | 必需 | [`AgentInstructionChange[]`](#persistence-type-sha256-2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee) | +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"agent-instructions"` | + + + + + + + +### `AgentMessageSource` + +SHA-256: `4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86` + +来源:[`packages/subagent/subagent/src/continuation-messages.ts:15`](../packages/subagent/subagent/src/continuation-messages.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"agent-message"` | +| `senderSessionId` | 必需 | `string` | + + + + + + + +### `ApprovalOutcome` + +SHA-256: `930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7` + +来源:[`packages/interaction/user-approval/src/types.ts:32`](../packages/interaction/user-approval/src/types.ts) + +以下类型之一: + +- `"allowed-once"` +- `"cancelled"` +- `"rejected"` +- `"unavailable"` + + + + + + + +### `ApprovalPolicy` + +SHA-256: `05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf` + +来源:[`packages/interaction/user-approval/src/index.ts:67`](../packages/interaction/user-approval/src/index.ts) + +以下类型之一: + +- `"ask"` +- `"never"` + + + + + + + +### `AssistantMessage` + +SHA-256: `fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be` + +来源:[`packages/llm/llm/src/message.ts:167`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"assistant"` | +| `source` | 必需 | [`ModelMessageSource`](#persistence-type-sha256-719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91) | + + + + + + + +### `AssistantStreamRecord` + +SHA-256: `33341aac09312300de5a178e6cc6f6544a4876f7f710cfea55eda473c8d329ef` + +来源:[`packages/llm/llm/src/assistant-stream.ts:20`](../packages/llm/llm/src/assistant-stream.ts) + +以下类型之一: + +- [`{ type: "tool-call-chunks" }`](#persistence-type-sha256-3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6) +- [`{ type: "chunk" }`](#persistence-type-sha256-487b65c37bfedb8b72088c4107a0a90a6249701f6b26745f6d98f9b8a22b07c7) +- [`{ type: "reasoning-chunks" }`](#persistence-type-sha256-71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd) +- [`{ type: "text-chunks" }`](#persistence-type-sha256-e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33) + + + +### `AssistantStreamRecord[]` + +SHA-256: `84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7` + +[`AssistantStreamRecord`](#persistence-type-sha256-33341aac09312300de5a178e6cc6f6544a4876f7f710cfea55eda473c8d329ef) 的数组。 + + + + + + + +### `AtScheduleRecord` + +SHA-256: `658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e` + +来源:[`packages/schedule/schedule/src/types.ts:27`](../packages/schedule/schedule/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `kind` | 必需 | `"at"` | +| `prompt` | 必需 | `string` | +| `scheduledAt` | 必需 | `string` | + + + + + + + +### `CommandSource` + +SHA-256: `ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05` + +来源:[`packages/core/session/src/types.ts:190`](../packages/core/session/src/types.ts) · [`packages/interaction/commands/src/types.ts:75`](../packages/interaction/commands/src/types.ts) · [`packages/interaction/commands/src/types.ts:79`](../packages/interaction/commands/src/types.ts) · [`packages/llm/llm/src/message.ts:111`](../packages/llm/llm/src/message.ts) · [`packages/session/session-title/src/types.ts:35`](../packages/session/session-title/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"user"` | + + + + + + + +### `CompactionCheckpointSource` + +SHA-256: `31907de9563751822af6d9be02bafaf26faa098bbd1cb412524134d577cc1648` + +来源:[`packages/compaction/compaction/src/checkpoint.ts:22`](../packages/compaction/compaction/src/checkpoint.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `kind` | 必需 | `"compact-checkpoint"` | +| `sourceCommandId` | 可选 | `string` | + + + + + + + +### `ContentBlock` + +SHA-256: `8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5` + +来源:[`packages/llm/llm/src/types.ts:151`](../packages/llm/llm/src/types.ts) + +以下类型之一: + +- [`ReasoningBlock`](#persistence-type-sha256-814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e) +- [`TextBlock`](#persistence-type-sha256-4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c) +- [`ToolAdditionBlock`](#persistence-type-sha256-8e611bf46821e5003a1605a73560a6f56388295149d449dfe2142d5ec335f29c) +- [`ToolRemovalBlock`](#persistence-type-sha256-43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8) +- [`ToolCallBlock`](#persistence-type-sha256-c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea) +- [`ImageBlock`](#persistence-type-sha256-12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7) +- [`FileBlock`](#persistence-type-sha256-f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef) + + + + + + + +### `ContentBlockType` + +SHA-256: `7d65acf0a3a43a8f445ce5d3320b42eca492739fc931b2a7516bfb8368dc2c68` + +来源:[`packages/llm/llm/src/types.ts:149`](../packages/llm/llm/src/types.ts) + +以下类型之一: + +- `"file"` +- `"image"` +- `"reasoning"` +- `"text"` +- `"tool-addition"` +- `"tool-call"` +- `"tool-removal"` + + + +### `ContentBlock[]` + +SHA-256: `b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1` + +[`ContentBlock`](#persistence-type-sha256-8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5) 的数组。 + + + + + + + +### `ContextSnapshotSection` + +SHA-256: `86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219` + +来源:[`packages/llm/llm/src/message.ts:70`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `name` | 必需 | `string` | +| `text` | 必需 | `string` | + + + +### `ContextSnapshotSection[]` + +SHA-256: `c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262` + +[`ContextSnapshotSection`](#persistence-type-sha256-86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219) 的数组。 + + + + + + + +### `ContinuableSubagentDescriptorData` + +SHA-256: `6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f` + +来源:[`packages/subagent/subagent/src/descriptor.ts:72`](../packages/subagent/subagent/src/descriptor.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentModel` | 可选 | `string` | +| `agentProvider` | 可选 | `string` | +| `agentReasoningEffort` | 可选 | `string` | +| `label` | 必需 | `string` | +| `mode` | 必需 | `"continuable"` | +| `persona` | 可选 | `string` | +| `provider` | 必需 | `string` | +| `toolFilter` | 可选 | [`ToolRestriction`](#persistence-type-sha256-3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f) | +| `version` | 必需 | `number` | + + + + + + + +### `DeepSeekSearchLlmRequest` + +SHA-256: `2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9` + +来源:[`packages/web/web-search-deepseek/src/provider.ts:55`](../packages/web/web-search-deepseek/src/provider.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `apiVersion` | 必需 | `string` | +| `body` | 必需 | [`{ max_tokens, messages, model, tools }`](#persistence-type-sha256-930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731) | +| `endpoint` | 必需 | `string` | + + + + + + + +### `DeveloperMessage` + +SHA-256: `f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b` + +来源:[`packages/llm/llm/src/message.ts:157`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"developer"` | +| `source` | 必需 | [`MessageSource`](#persistence-type-sha256-40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945) | + +消息源兼容策略:`source` — `session-source-attribution` v1; `session.developer-message.source`; `kind`; `preserve`. + +仅表示归属的新增 kind:`tmux-context`. + + + + + + + +### `EpochHeader` + +SHA-256: `9a930283b91d493d6347146f2475bb107294b379415ca02162354f46a64164f7` + +来源:[`packages/core/session/src/types.ts:240`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `adapterDefaults` | 可选 | [`LlmCallConfigAdapterDefaults`](#persistence-type-sha256-326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693) | +| `config` | 必需 | [`LlmCallConfig`](#persistence-type-sha256-67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0) | +| `system` | 可选 | `never` | +| `tools` | 可选 | [`ToolSchema[]`](#persistence-type-sha256-a0baff42eb900561f91032b6950a3925cf19c5c8d9ba33948ac69e4ac7dee573) | + + + + + + + +### `EveryScheduleDispatchChange` + +SHA-256: `e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344` + +来源:[`packages/schedule/schedule/src/types.ts:93`](../packages/schedule/schedule/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `acceptedAt` | 必需 | `string` | +| `id` | 必需 | `string` | +| `operation` | 必需 | `"dispatch"` | +| `version` | 必需 | `1` | + + + + + + + +### `EveryScheduleRecord` + +SHA-256: `66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14` + +来源:[`packages/schedule/schedule/src/types.ts:39`](../packages/schedule/schedule/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `everySeconds` | 必需 | `number` | +| `id` | 必需 | `string` | +| `kind` | 必需 | `"every"` | +| `prompt` | 必需 | `string` | +| `scheduledAt` | 必需 | `string` | + + + + + + + +### `FeedbackRecord` + +SHA-256: `7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344` + +来源:[`packages/feedback/command-feedback/src/types.ts:27`](../packages/feedback/command-feedback/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `category` | 可选 | [`union (7 variants)`](#persistence-type-sha256-3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd) | +| `text` | 可选 | `string` | + + + + + + + +### `FileAttachmentRef` + +SHA-256: `f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6` + +来源:[`packages/attachment/attachment/src/types.ts:39`](../packages/attachment/attachment/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachmentId` | 必需 | `string` | +| `bytes` | 必需 | `number` | +| `name` | 必需 | `string` | + + + + + + + +### `FileBlock` + +SHA-256: `f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef` + +来源:[`packages/llm/llm/src/types.ts:98`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachment` | 必需 | [`FileAttachmentRef`](#persistence-type-sha256-f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6) | +| `type` | 必需 | `"file"` | + + + + + + + +### `FinishReason` + +SHA-256: `5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80` + +来源:[`packages/llm/llm/src/types.ts:166`](../packages/llm/llm/src/types.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `aborted` | 未声明 | `failure`: [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | [`{ failure, kind: "aborted" }`](#persistence-type-sha256-8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0) | +| `error` | 未声明 | `failure`: [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | [`{ failure, kind: "error" }`](#persistence-type-sha256-693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057) | +| `max-tokens` | 未声明 | 无 | [`{ kind: "max-tokens" }`](#persistence-type-sha256-ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7) | +| `stop` | 未声明 | 无 | [`{ kind: "stop" }`](#persistence-type-sha256-1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f) | +| `tool-calls` | 未声明 | 无 | [`{ kind: "tool-calls" }`](#persistence-type-sha256-287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a) | + + + + + + + +### `GoalBlockReason` + +SHA-256: `84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c` + +来源:[`packages/goal/goal/src/types.ts:52`](../packages/goal/goal/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `code` | 必需 | `string` | +| `message` | 必需 | `string` | + + + + + + + +### `GoalChangeMeta` + +SHA-256: `7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438` + +来源:[`packages/goal/goal/src/domain.ts:44`](../packages/goal/goal/src/domain.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `goal/change` | 未声明 | `createdAt`: `number`; `goal`: [`GoalSnapshot`](#persistence-type-sha256-6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25); `operation`: [`union (6 variants)`](#persistence-type-sha256-62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379); `roundsStarted`: `number`; `updatedAt`: `number`; `version`: `1` | [`GoalSnapshotChangeMeta`](#persistence-type-sha256-1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4) | +| `goal/change` | 未声明 | `cleared`: [`GoalRef`](#persistence-type-sha256-0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f); `clearedAt`: `number`; `operation`: `"clear"`; `version`: `1` | [`GoalClearChangeMeta`](#persistence-type-sha256-cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f) | + + + + + + + +### `GoalClearChangeMeta` + +SHA-256: `cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f` + +来源:[`packages/goal/goal/src/domain.ts:35`](../packages/goal/goal/src/domain.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `cleared` | 必需 | [`GoalRef`](#persistence-type-sha256-0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f) | +| `clearedAt` | 必需 | `number` | +| `kind` | 必需 | `"goal/change"` | +| `operation` | 必需 | `"clear"` | +| `version` | 必需 | `1` | + + + + + + + +### `GoalMessageSource` + +SHA-256: `7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc` + +来源:[`packages/goal/goal/src/domain.ts:47`](../packages/goal/goal/src/domain.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `goalId` | 必需 | `string` | +| `kind` | 必需 | `"goal"` | +| `revision` | 必需 | `number` | +| `round` | 必需 | `number` | + + + + + + + +### `GoalPhase` + +SHA-256: `b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172` + +来源:[`packages/goal/goal/src/types.ts:45`](../packages/goal/goal/src/types.ts) + +以下类型之一: + +- `"active"` +- `"blocked"` +- `"complete"` +- `"paused"` + + + + + + + +### `GoalRef` + +SHA-256: `0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f` + +来源:[`packages/goal/goal/src/types.ts:20`](../packages/goal/goal/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `revision` | 必需 | `number` | + + + + + + + +### `GoalSnapshot` + +SHA-256: `6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25` + +来源:[`packages/goal/goal/src/types.ts:60`](../packages/goal/goal/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blockedReason` | 可选 | [`GoalBlockReason`](#persistence-type-sha256-84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c) | +| `id` | 必需 | `string` | +| `maxGoalRounds` | 必需 | `number` | +| `objective` | 必需 | `string` | +| `phase` | 必需 | [`GoalPhase`](#persistence-type-sha256-b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172) | +| `revision` | 必需 | `number` | + + + + + + + +### `GoalSnapshotChangeMeta` + +SHA-256: `1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4` + +来源:[`packages/goal/goal/src/domain.ts:24`](../packages/goal/goal/src/domain.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `createdAt` | 必需 | `number` | +| `goal` | 必需 | [`GoalSnapshot`](#persistence-type-sha256-6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25) | +| `kind` | 必需 | `"goal/change"` | +| `operation` | 必需 | [`union (6 variants)`](#persistence-type-sha256-62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379) | +| `roundsStarted` | 必需 | `number` | +| `updatedAt` | 必需 | `number` | +| `version` | 必需 | `1` | + + + + + + + + + +### `HeaderLine` + +SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` + +来源:[`packages/session/session-persistence-jsonl/src/format.ts:83`](../packages/session/session-persistence-jsonl/src/format.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentPreset` | 可选 | `string` | +| `createdAt` | 必需 | `number` | +| `cwd` | 可选 | `string` | +| `delegationDepth` | 必需 | `number` | +| `id` | 必需 | `string` | +| `isSeeded` | 必需 | `boolean` | +| `origin` | 可选 | `"subagent"` | +| `parentSession` | 可选 | `string` | +| `type` | 必需 | `"session"` | +| `version` | 必需 | `number` | + + + + + + + +### `HookDialect` + +SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` + +来源:[`packages/hooks/hook-protocol/src/types.ts:48`](../packages/hooks/hook-protocol/src/types.ts) + +以下类型之一: + +- `"claude-code"` +- `"codex"` + + + + + + + +### `ImageAttachmentRef` + +SHA-256: `b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35` + +来源:[`packages/attachment/attachment/src/types.ts:11`](../packages/attachment/attachment/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachmentId` | 必需 | `string` | +| `bytes` | 必需 | `number` | +| `height` | 必需 | `number` | +| `mediaType` | 必需 | [`ImageMediaType`](#persistence-type-sha256-2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716) | +| `name` | 可选 | `string` | +| `originalDimensions` | 可选 | [`{ height, width }`](#persistence-type-sha256-0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef) | +| `width` | 必需 | `number` | + + + + + + + +### `ImageBlock` + +SHA-256: `12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7` + +来源:[`packages/llm/llm/src/types.ts:79`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachment` | 必需 | [`ImageAttachmentRef`](#persistence-type-sha256-b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35) | +| `offloaded` | 可选 | `true` | +| `type` | 必需 | `"image"` | + + + + + + + +### `ImageMediaType` + +SHA-256: `2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716` + +来源:[`packages/attachment/attachment/src/types.ts:8`](../packages/attachment/attachment/src/types.ts) + +以下类型之一: + +- `"image/gif"` +- `"image/jpeg"` +- `"image/png"` +- `"image/webp"` + + + + + + + +### `ImageOffloadTarget` + +SHA-256: `1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f` + +来源:[`packages/compaction/compaction-image-offload/src/projection.ts:9`](../packages/compaction/compaction-image-offload/src/projection.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `imageIndexes` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `seq` | 必需 | `number` | + + + +### `ImageOffloadTarget[]` + +SHA-256: `9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb` + +[`ImageOffloadTarget`](#persistence-type-sha256-1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f) 的数组。 + + + + + + + +### `InboxTarget` + +SHA-256: `96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c` + +来源:[`packages/core/agent/src/types.ts:30`](../packages/core/agent/src/types.ts) + +以下类型之一: + +- `"next-step"` +- `"next-turn"` + + + + + + + +### `JsonValue` + +SHA-256: `c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6` + +来源:[`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) + +以下类型之一: + +- [`JsonValue[]`](#persistence-type-sha256-72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227) +- [`{}`](#persistence-type-sha256-529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05) +- `string` +- `boolean` +- `null` +- `number` + + + +### `JsonValue[]` + +SHA-256: `72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227` + +[`JsonValue`](#persistence-type-sha256-c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6) 的数组。 + + + + + + + +### `LlmCallConfig` + +SHA-256: `67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0` + +来源:[`packages/llm/llm/src/call-config.ts:23`](../packages/llm/llm/src/call-config.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `maxTokens` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `reasoningEffort` | 可选 | `string` | +| `stop` | 可选 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `temperature` | 可选 | `number` | + + + + + + + +### `LlmCallConfigAdapterDefaults` + +SHA-256: `326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693` + +来源:[`packages/llm/llm/src/call-config.ts:36`](../packages/llm/llm/src/call-config.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `maxTokens` | 可选 | `true` | +| `reasoningEffort` | 可选 | `true` | + + + + + + + +### `LlmFailure` + +SHA-256: `5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca` + +来源:[`packages/llm/llm/src/types.ts:41`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `code` | 必需 | `string` | +| `message` | 必需 | `string` | +| `offloadImages` | 可选 | `number` | +| `providerRetryAfterMs` | 可选 | `number` | +| `requestId` | 可选 | `string` | +| `status` | 可选 | `number` | + + + + + + + +### `LlmRetryEventData` + +SHA-256: `c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1` + +来源:[`packages/llm/llm-retry/src/types.ts:16`](../packages/llm/llm-retry/src/types.ts) + +以下类型之一: + +- [`{ delayMs, failure, maxRetries, mode, … }`](#persistence-type-sha256-cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced) +- [`{ delayMs, failure, mode, policyKey, … }`](#persistence-type-sha256-374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b) + + + + + + + +### `LlmRetryStartedEventData` + +SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20` + +来源:[`packages/llm/llm-retry/src/types.ts:43`](../packages/llm/llm-retry/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `retry` | 必需 | `number` | +| `retryId` | 必需 | `string` | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + + + + + +### `Message` + +SHA-256: `691c0f641cd3e8072fdacd6fa8c400253cf75a0ce9285d8ce89141bbb24f2fb6` + +来源:[`packages/llm/llm/src/message.ts:196`](../packages/llm/llm/src/message.ts) + +以下类型之一: + +- [`ToolResultMessage`](#persistence-type-sha256-4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731) +- [`DeveloperMessage`](#persistence-type-sha256-f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b) +- [`UserMessage`](#persistence-type-sha256-64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586) +- [`AssistantMessage`](#persistence-type-sha256-fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be) +- [`SystemMessage`](#persistence-type-sha256-09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363) + + + + + + + +### `MessageFeedbackDelete` + +SHA-256: `7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06` + +来源:[`packages/feedback/message-feedback/src/types.ts:46`](../packages/feedback/message-feedback/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `messageId` | 必需 | `string` | +| `sessionId` | 必需 | `string` | + + + + + + + +### `MessageFeedbackItem` + +SHA-256: `3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182` + +来源:[`packages/feedback/message-feedback/src/types.ts:20`](../packages/feedback/message-feedback/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `category` | 可选 | [`union (7 variants)`](#persistence-type-sha256-3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd) | +| `createdAt` | 必需 | `number` | +| `messageId` | 必需 | `string` | +| `note` | 可选 | `string` | +| `rating` | 必需 | [`MessageFeedbackRating`](#persistence-type-sha256-390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2) | +| `updatedAt` | 必需 | `number` | +| `version` | 必需 | `string` | + + + + + + + +### `MessageFeedbackPut` + +SHA-256: `aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626` + +来源:[`packages/feedback/message-feedback/src/types.ts:38`](../packages/feedback/message-feedback/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `item` | 必需 | [`MessageFeedbackItem`](#persistence-type-sha256-3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182) | +| `sessionId` | 必需 | `string` | + + + + + + + +### `MessageFeedbackRating` + +SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2` + +来源:[`packages/feedback/message-feedback/src/types.ts:17`](../packages/feedback/message-feedback/src/types.ts) + +以下类型之一: + +- `"negative"` +- `"positive"` + + + + + + + +### `MessageSource` + +SHA-256: `40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945` + +来源:[`packages/llm/llm/src/message.ts:136`](../packages/llm/llm/src/message.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `agent-instructions` | `"instructions"` | `changes`: [`AgentInstructionChange[]`](#persistence-type-sha256-2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee) | [`AgentInstructionSource`](#persistence-type-sha256-6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590) | +| `agent-message` | `"relay"` | `senderSessionId`: `string` | [`AgentMessageSource`](#persistence-type-sha256-4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86) | +| `compact-checkpoint` | 未声明 | `compactionId`: `string` | [`CompactionCheckpointSource`](#persistence-type-sha256-31907de9563751822af6d9be02bafaf26faa098bbd1cb412524134d577cc1648) | +| `cordis-host-runner` | 未声明 | 无 | [`{ kind: "cordis-host-runner" }`](#persistence-type-sha256-02b2c23f2d94b028c9588a8faace3fce1217405db346da3389368b495457bf79) | +| `dsh-session-title-llm` | `"catalog"` | 无 | [`{ kind: "dsh-session-title-llm", form: "catalog" }`](#persistence-type-sha256-80677c8c8b804189a0fde8aa70dd4ad7af8bb12dfd03027e8e023c8592c838bc) | +| `dsh-session-title-llm` | `"instructions"` | 无 | [`{ kind: "dsh-session-title-llm", form: "instructions" }`](#persistence-type-sha256-224aa11d4d5f88c450822d01b99e6ca5e3a9c7f26a5ede10bae33384a09ef4dc) | +| `dsh-session-title-llm` | `"notice"` | `summary`: `string` | [`{ kind: "dsh-session-title-llm", form: "notice" }`](#persistence-type-sha256-8338ee303e2bd448e9e6144069942f63e3cfd5868962bddc9347d7009e8919d6) | +| `dsh-session-title-llm` | `"recall"` | 无 | [`{ kind: "dsh-session-title-llm", form: "recall" }`](#persistence-type-sha256-b2a5c8c008a31e3dc6c3013502f2356aca13894b31c8e70601fa92f2d40d1dba) | +| `dsh-session-title-llm` | `"relay"` | 无 | [`{ kind: "dsh-session-title-llm", form: "relay" }`](#persistence-type-sha256-7eaef7a763ba5b949b8464bc8add8980a3a5ab566014b69787aeba71e5dfe07b) | +| `dsh-session-title-llm` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "dsh-session-title-llm", form: "snapshot" }`](#persistence-type-sha256-ba4c40b4381e0dcdfab8fc9fc75b5c9b3e8f09ef56deeb1bec8e703b0ef8cd6d) | +| `dsh-session-title-llm` | 未声明 | 无 | [`{ kind: "dsh-session-title-llm" }`](#persistence-type-sha256-290f32bfd81ff85a8095886a8066fae06e885942b63a8bcd6a8d66d328445808) | +| `goal` | 未声明 | `goalId`: `string`; `revision`: `number`; `round`: `number` | [`GoalMessageSource`](#persistence-type-sha256-7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc) | +| `hooks-claude-code` | `"catalog"` | 无 | [`{ kind: "hooks-claude-code", form: "catalog" }`](#persistence-type-sha256-297fbd8067d7815adae02b89790ec6ff5fb7c2cb0d0eb026e1746c24ec857761) | +| `hooks-claude-code` | `"instructions"` | 无 | [`{ kind: "hooks-claude-code", form: "instructions" }`](#persistence-type-sha256-b70f3e81fe11b7a5f2504fb47a4502fb8d9c8f0731fdfe8ddcaf9b41f5a6e196) | +| `hooks-claude-code` | `"notice"` | `summary`: `string` | [`{ kind: "hooks-claude-code", form: "notice" }`](#persistence-type-sha256-edbbfff1128099fda7b792c56330d2cb04debc9790988e66d1c3f4026e813e0e) | +| `hooks-claude-code` | `"recall"` | 无 | [`{ kind: "hooks-claude-code", form: "recall" }`](#persistence-type-sha256-87b1a33564b9a4d63b00988a524c12259243953aebb9c9a05127d87b27464df9) | +| `hooks-claude-code` | `"relay"` | 无 | [`{ kind: "hooks-claude-code", form: "relay" }`](#persistence-type-sha256-6ea608bdc8a7a63d3d23b84c49721325094db88d136482e43a820945295eee3e) | +| `hooks-claude-code` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "hooks-claude-code", form: "snapshot" }`](#persistence-type-sha256-3bdb8dc6989655b0d4ec361edafb8e2629bc263e1ea591819414fdafc1a413b3) | +| `hooks-claude-code` | 未声明 | 无 | [`{ kind: "hooks-claude-code" }`](#persistence-type-sha256-0ed8d1108fe7a5e1c3078ef1faea12199a56b6b1216ccaceb0f6103b0c9a7691) | +| `hooks-codex` | `"catalog"` | 无 | [`{ kind: "hooks-codex", form: "catalog" }`](#persistence-type-sha256-99f0e98184709ad10f27bfdeaafb4457d9d2b413f402331764798cdb7d3cbe4d) | +| `hooks-codex` | `"instructions"` | 无 | [`{ kind: "hooks-codex", form: "instructions" }`](#persistence-type-sha256-b6f94c17dd9bbd7cd57015198b7c7c88407f0e3b89faab176ca3c11c3d864d3e) | +| `hooks-codex` | `"notice"` | `summary`: `string` | [`{ kind: "hooks-codex", form: "notice" }`](#persistence-type-sha256-854db3efdfb0cd39d30953b28703e519c121f1115cebfffc40369fe86c406dd1) | +| `hooks-codex` | `"recall"` | 无 | [`{ kind: "hooks-codex", form: "recall" }`](#persistence-type-sha256-3b4f2c9ef2c1217eac596c7b070173cb7896e2fae09e729bc7c56c801e56bb29) | +| `hooks-codex` | `"relay"` | 无 | [`{ kind: "hooks-codex", form: "relay" }`](#persistence-type-sha256-1fdad624334d354820dfb3a26e28d0bc9fc1b62a33f87bab63f715b3f4391bfd) | +| `hooks-codex` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "hooks-codex", form: "snapshot" }`](#persistence-type-sha256-88841202942c7683b3b7e5ea6a796047ec326b6701ac23e58cc236d85613b9fa) | +| `hooks-codex` | 未声明 | 无 | [`{ kind: "hooks-codex" }`](#persistence-type-sha256-b4ec0af39fd52ed971990e42f04e5be3204882e555c409eb330f8238eec21569) | +| `model` | 未声明 | `model`: `string`; `provider`: `string` | [`ModelMessageSource`](#persistence-type-sha256-719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91) | +| `model-selection` | `"catalog"` | 无 | [`{ kind: "model-selection", form: "catalog" }`](#persistence-type-sha256-99135d8a3937977955eaac5f8f04f930dcd1562f8450a54a51cde9b921dd59a6) | +| `model-selection` | `"instructions"` | 无 | [`{ kind: "model-selection", form: "instructions" }`](#persistence-type-sha256-f6605d6c57933aeaaf10911b5fbd6c61e655baa181af7192d3240f49d255b90d) | +| `model-selection` | `"notice"` | `summary`: `string` | [`{ kind: "model-selection", form: "notice" }`](#persistence-type-sha256-a3c6f1ea38e9a61d7a9706057ba65aabe02dfe6d9dd90d4736aa62325d874531) | +| `model-selection` | `"recall"` | 无 | [`{ kind: "model-selection", form: "recall" }`](#persistence-type-sha256-aae343bc3d663c83f2e8b5e1c7eea5d509dc7a5361bc8bd8b5ac3bb8d3b1ed56) | +| `model-selection` | `"relay"` | 无 | [`{ kind: "model-selection", form: "relay" }`](#persistence-type-sha256-a15a19ef63cf5d1b711db1d249821dab0cedcd3a9ad09137b47352c93841fd20) | +| `model-selection` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "model-selection", form: "snapshot" }`](#persistence-type-sha256-52c6113cb0e53f345324bf84f01928bea5d5df57ee80bc0dd65407b8bc5a3734) | +| `model-selection` | 未声明 | 无 | [`{ kind: "model-selection" }`](#persistence-type-sha256-f7283223aacdc39b0adca728c8cbd4c090a20006a6fecec74421c30e943b489c) | +| `plan-mode` | `"catalog"` | 无 | [`{ kind: "plan-mode", form: "catalog" }`](#persistence-type-sha256-3b04790e08b35241ffa0d38f6d7e4f8788aa921341f6c0d7574a329397c59408) | +| `plan-mode` | `"instructions"` | 无 | [`{ kind: "plan-mode", form: "instructions" }`](#persistence-type-sha256-408927267422a7b2beb6df354ff7c1406d929a5646554f48adf85eb8372f811c) | +| `plan-mode` | `"notice"` | `summary`: `string` | [`{ kind: "plan-mode", form: "notice" }`](#persistence-type-sha256-baccc97ec34be6c4c78e95aa88c85c29820269479445e5b13f956cd64c5e286f) | +| `plan-mode` | `"recall"` | 无 | [`{ kind: "plan-mode", form: "recall" }`](#persistence-type-sha256-f6329fb30c7ea8013e8975ca5e78284fb7685cc6bd620e8aa4e9a99bc81d45eb) | +| `plan-mode` | `"relay"` | 无 | [`{ kind: "plan-mode", form: "relay" }`](#persistence-type-sha256-deaae5cd30987d4f49398e8f9d994c125907e7f928300745fb1dbf15f145d0e7) | +| `plan-mode` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "plan-mode", form: "snapshot" }`](#persistence-type-sha256-8c1c4f72755a78ea163523a46565316e36e9b644382eb48e6635c71a6f412dd2) | +| `plan-mode` | 未声明 | 无 | [`{ kind: "plan-mode" }`](#persistence-type-sha256-f4a66f654996c093aae700ea4c434ff2ee3569fea9c0e5813ccf6afdccabd163) | +| `ptc-mode` | 未声明 | 无 | [`{ kind: "ptc-mode" }`](#persistence-type-sha256-dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd) | +| `repeat-tool-reminder` | `"catalog"` | 无 | [`{ kind: "repeat-tool-reminder", form: "catalog" }`](#persistence-type-sha256-d85590a5675c6e2fd8164e5792a6cceac714605b8ac228adae5ee668facb1490) | +| `repeat-tool-reminder` | `"instructions"` | 无 | [`{ kind: "repeat-tool-reminder", form: "instructions" }`](#persistence-type-sha256-6f44f32be9bcd9a8bf075c3b575b06c8ed63446386e5b0995c7b73762e68ddae) | +| `repeat-tool-reminder` | `"notice"` | `summary`: `string` | [`{ kind: "repeat-tool-reminder", form: "notice" }`](#persistence-type-sha256-fe1a7acdeed4d0f5ab483396eaa5b3dc97263b7c10eb4da2f0028cb01728bfc9) | +| `repeat-tool-reminder` | `"recall"` | 无 | [`{ kind: "repeat-tool-reminder", form: "recall" }`](#persistence-type-sha256-8620189c8e33582708ece48fd2d20dc4d57912486a17bdbb9aea4c44f7018062) | +| `repeat-tool-reminder` | `"relay"` | 无 | [`{ kind: "repeat-tool-reminder", form: "relay" }`](#persistence-type-sha256-4991dfc415c9efebc36fa6969e1798c7d2e42396cc1e6e0ac7d7c89c5c5c4aea) | +| `repeat-tool-reminder` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "repeat-tool-reminder", form: "snapshot" }`](#persistence-type-sha256-db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c) | +| `repeat-tool-reminder` | 未声明 | 无 | [`{ kind: "repeat-tool-reminder" }`](#persistence-type-sha256-b062078e899958f99ae464514578b8c093924dfe34bd9a835932b420ff2150b1) | +| `runtime-context` | `"catalog"` | 无 | [`{ kind: "runtime-context", form: "catalog" }`](#persistence-type-sha256-58015da1c1950a66daf66ae24913d6a1fc6d1d9ac441b155f8847f7f8584ba8e) | +| `runtime-context` | `"instructions"` | 无 | [`{ kind: "runtime-context", form: "instructions" }`](#persistence-type-sha256-0eeb17e1df89b1ebc2902116fe7145e0d321ef0db26e6bdebc802cb8513a01c1) | +| `runtime-context` | `"notice"` | `summary`: `string` | [`{ kind: "runtime-context", form: "notice" }`](#persistence-type-sha256-cda2345a9be9d139df49ccbd16dcba716f3440178bf20ff8b801fda1f5eb77dc) | +| `runtime-context` | `"recall"` | 无 | [`{ kind: "runtime-context", form: "recall" }`](#persistence-type-sha256-96bfb916a727cd4445a594df264c523fc039749a31bfed924b8cc7bb308a5bb0) | +| `runtime-context` | `"relay"` | 无 | [`{ kind: "runtime-context", form: "relay" }`](#persistence-type-sha256-cb1c8959e1726f82f9a3d2ef2bc90bf8c451a98fd56175e956022124c770c818) | +| `runtime-context` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "runtime-context", form: "snapshot" }`](#persistence-type-sha256-2aad1179f957631477b582e57cd8f538cb82618fc3fb816bde1171154235b065) | +| `runtime-context` | 未声明 | 无 | [`{ kind: "runtime-context" }`](#persistence-type-sha256-0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789) | +| `schedule` | `"catalog"` | 无 | [`{ kind: "schedule", form: "catalog" }`](#persistence-type-sha256-1e709346005826eb81809eeb76a3f713cf13ad6c5cec75146d07020ab9adc938) | +| `schedule` | `"instructions"` | 无 | [`{ kind: "schedule", form: "instructions" }`](#persistence-type-sha256-1938c8c20f1cba7c82dbedcfa4f14c3ee191cd77ed3314ee1fc676d44cadf3be) | +| `schedule` | `"notice"` | `summary`: `string` | [`{ kind: "schedule", form: "notice" }`](#persistence-type-sha256-312aee2f0c42aabbae6cc60d92d596d8453c0aeb061c5868d1755a69ef49e69a) | +| `schedule` | `"recall"` | 无 | [`{ kind: "schedule", form: "recall" }`](#persistence-type-sha256-a16e567c8cd2c55cf1e911aed3c200c4e1f6febb1459ff2a9e7adf159afb68cb) | +| `schedule` | `"relay"` | 无 | [`{ kind: "schedule", form: "relay" }`](#persistence-type-sha256-5bc66269cfaf614c0ecda8ecb469f23101a7609793fc2b693ac23c4aecdb575e) | +| `schedule` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "schedule", form: "snapshot" }`](#persistence-type-sha256-28936c614bd4e7e2774806edcbb3cbfd3ee643ac1cbf0bbdff43d915505a8fe3) | +| `schedule` | 未声明 | 无 | [`{ kind: "schedule" }`](#persistence-type-sha256-f29d63336e8266d80dd7baeab219436db86341304f6be1cd0edb36f5134c4a47) | +| `session-reference` | `"recall"` | `references`: [`{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }[]`](#persistence-type-sha256-df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18); `version`: `1` | [`SessionReferenceSource`](#persistence-type-sha256-f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f) | +| `skill-catalog` | `"catalog"` | `entries`: [`{ description, name }[]`](#persistence-type-sha256-aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba) | [`SkillCatalogSource`](#persistence-type-sha256-fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093) | +| `skill-invocation` | `"instructions"` | `name`: `string` | [`SkillInvocationSource`](#persistence-type-sha256-672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db) | +| `subagent-settled` | `"notice"` | `senderSessionId`: `string`; `summary`: `string` | [`SubagentSettledMessageSource`](#persistence-type-sha256-4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a) | +| `system-prompt` | 未声明 | 无 | [`SystemPromptMessageSource`](#persistence-type-sha256-65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad) | +| `team-message` | 未声明 | `messageId`: `string`; `senderId`: `string`; `senderName`: `string`; `teamId`: `string` | [`TeamMessageSource`](#persistence-type-sha256-2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0) | +| `time-context` | `"catalog"` | 无 | [`{ kind: "time-context", form: "catalog" }`](#persistence-type-sha256-85fe96bf15d5c7559eec3bae4d6cf1a76fda9f5be05a29c2830cff560cab0c0d) | +| `time-context` | `"instructions"` | 无 | [`{ kind: "time-context", form: "instructions" }`](#persistence-type-sha256-f6afe41e3926f422fe849debe90819fddd739f0f59e20be9c71018b9554a7f09) | +| `time-context` | `"notice"` | `summary`: `string` | [`{ kind: "time-context", form: "notice" }`](#persistence-type-sha256-ee577a0cc18664c9daee50e9455153321155604f8f1817362f8f4a4b6fb9e1ad) | +| `time-context` | `"recall"` | 无 | [`{ kind: "time-context", form: "recall" }`](#persistence-type-sha256-756b5e23a5cb2c7f486f366a828f7461c88902af21125bd6810881f4ccbff6cc) | +| `time-context` | `"relay"` | 无 | [`{ kind: "time-context", form: "relay" }`](#persistence-type-sha256-5d7a64ed6aac5551ebf998dc25e1e7b48a144769913f89702840180e61dc3995) | +| `time-context` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "time-context", form: "snapshot" }`](#persistence-type-sha256-f230c0b583e23b25ee0a61dbe4c05e95c1e2ae44b27939501eb9e03696f0c278) | +| `time-context` | 未声明 | 无 | [`{ kind: "time-context" }`](#persistence-type-sha256-b79641a9d25e756636dc0c706fdf3c4583ccb7d4920e009e6e86c0759cf4de4c) | +| `tmux-context` | `"catalog"` | 无 | [`{ kind: "tmux-context", form: "catalog" }`](#persistence-type-sha256-7df62978a2b7de8540e714152297743e0a622209a46a5ac9513fc0fad73ca23b) | +| `tmux-context` | `"instructions"` | 无 | [`{ kind: "tmux-context", form: "instructions" }`](#persistence-type-sha256-9f65c43e340bba31cdc0fc37bd93ccb68d5e9b36f47a68c207e95a8e68620a5d) | +| `tmux-context` | `"notice"` | `summary`: `string` | [`{ kind: "tmux-context", form: "notice" }`](#persistence-type-sha256-b3681c026a0b98e98b103f057dfd217fbe904129c090efd668253ec9aea7fece) | +| `tmux-context` | `"recall"` | 无 | [`{ kind: "tmux-context", form: "recall" }`](#persistence-type-sha256-fcf81d3c58c13593bf2594e342e31734f4ab2d24938dc610875194c6079749c7) | +| `tmux-context` | `"relay"` | 无 | [`{ kind: "tmux-context", form: "relay" }`](#persistence-type-sha256-f97f47b0eb87905ed77cc27c5e4ed75ef805cb372c98905253709de1aab9b63c) | +| `tmux-context` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "tmux-context", form: "snapshot" }`](#persistence-type-sha256-49dab019d00e8c26f27ad2ccff7b604d69e323ae4d17e0d2a7b6b8a830b1ade2) | +| `tmux-context` | 未声明 | 无 | [`{ kind: "tmux-context" }`](#persistence-type-sha256-8a046b52331959aa3394680d6acbe09b8a5447c6b61375f263445bfcef19b7f1) | +| `tool` | 未声明 | `callId`: `string` | [`ToolMessageSource`](#persistence-type-sha256-d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab) | +| `tool-goal` | `"catalog"` | 无 | [`{ kind: "tool-goal", form: "catalog" }`](#persistence-type-sha256-260523b412c19ad8c2bb00093b07f64245ff8ba6b2f76c5b545303772ac9704c) | +| `tool-goal` | `"instructions"` | 无 | [`{ kind: "tool-goal", form: "instructions" }`](#persistence-type-sha256-6085488d223aeffdef51d7ae17655fc26ab22ee13cbed82a50e62e2b6fb5b918) | +| `tool-goal` | `"notice"` | `summary`: `string` | [`{ kind: "tool-goal", form: "notice" }`](#persistence-type-sha256-8c627d7a45fa406cea879a3922105e27ed4c3c7966e264afaf11ea7a330f2dd1) | +| `tool-goal` | `"recall"` | 无 | [`{ kind: "tool-goal", form: "recall" }`](#persistence-type-sha256-7554565be416b0342053ee6a46256c9dab07c487349b4a5f10bab1edc151c619) | +| `tool-goal` | `"relay"` | 无 | [`{ kind: "tool-goal", form: "relay" }`](#persistence-type-sha256-8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4) | +| `tool-goal` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "tool-goal", form: "snapshot" }`](#persistence-type-sha256-11638dc58a31496fb6706ced3e23e3a2db1f3b2a8845968c810827a72b5fc811) | +| `tool-goal` | 未声明 | 无 | [`{ kind: "tool-goal" }`](#persistence-type-sha256-a2066bd52f61218ba15b758def2641cc6a8bd3d4a594a488ee4c65be356d7e39) | +| `tool-jobs` | `"catalog"` | 无 | [`{ kind: "tool-jobs", form: "catalog" }`](#persistence-type-sha256-dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5) | +| `tool-jobs` | `"instructions"` | 无 | [`{ kind: "tool-jobs", form: "instructions" }`](#persistence-type-sha256-53cf1704ae0709c7678bcf070c83c619fc48ca1b5c173b74cfa8702f22a8e492) | +| `tool-jobs` | `"notice"` | `summary`: `string` | [`{ kind: "tool-jobs", form: "notice" }`](#persistence-type-sha256-5bb69b88517f6214f2af4d1a6d2b771e271ad3ad695cc9c2c272069ae698c9bc) | +| `tool-jobs` | `"recall"` | 无 | [`{ kind: "tool-jobs", form: "recall" }`](#persistence-type-sha256-dd6cc2bb2a8f28248347021ad93565360b196a042360b4cd16b569d3a2a91f2d) | +| `tool-jobs` | `"relay"` | 无 | [`{ kind: "tool-jobs", form: "relay" }`](#persistence-type-sha256-ade057f4fdc387aec6426f48704a1f9359cfc6fee13f27735b07f9b215ec16ca) | +| `tool-jobs` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "tool-jobs", form: "snapshot" }`](#persistence-type-sha256-c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49) | +| `tool-jobs` | 未声明 | 无 | [`{ kind: "tool-jobs" }`](#persistence-type-sha256-24ce31aa528272e59f21cd26da9eca08968bcc97529756a749bfdab71746d9c8) | +| `tool-registry` | 未声明 | 无 | [`{ kind: "tool-registry" }`](#persistence-type-sha256-8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543) | +| `user` | 未声明 | `rpcId`: `string` | [`{ kind: "user" }`](#persistence-type-sha256-6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7) | +| `user` | 未声明 | 无 | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | +| `user-approval` | `"catalog"` | 无 | [`{ kind: "user-approval", form: "catalog" }`](#persistence-type-sha256-825ca23416b1ea9d81442afead5cf9229a6fa05842f042135cc3aa9710a6a2d8) | +| `user-approval` | `"instructions"` | 无 | [`{ kind: "user-approval", form: "instructions" }`](#persistence-type-sha256-aa2bf9e82b9fdeb94a42af20031fffa30e4e23f01f4ac39757427d4c64c407f0) | +| `user-approval` | `"notice"` | `summary`: `string` | [`{ kind: "user-approval", form: "notice" }`](#persistence-type-sha256-6ccb6bc423fb3952458abf9c1b1c3284208b7e660344b612cc55da773d61afe4) | +| `user-approval` | `"recall"` | 无 | [`{ kind: "user-approval", form: "recall" }`](#persistence-type-sha256-022623b9ef98ec47ec3c3bae0c51027c70d2601141c5e92e26a0d83d1b4cef06) | +| `user-approval` | `"relay"` | 无 | [`{ kind: "user-approval", form: "relay" }`](#persistence-type-sha256-5cdbf342b7748d152bc987b68f58e565e5bba4b227e076e2d2120d87662e45cd) | +| `user-approval` | `"snapshot"` | `sections`: [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | [`{ kind: "user-approval", form: "snapshot" }`](#persistence-type-sha256-5654685d7557ec747e74887237065e626a5bdfa426ca43f7fbb0b6fee9b0916c) | +| `user-approval` | 未声明 | 无 | [`{ kind: "user-approval" }`](#persistence-type-sha256-6292bcbedaa97feaec5b48a03bb8144b581b93309d9d6c905f26da7a6a7a0a4f) | +| `webhook` | `"notice"` | `deliveryId`: `string`; `provider`: `string`; `ruleId`: `string`; `source`: `string`; `summary`: `string` | [`{ kind: "webhook", form: "notice" }`](#persistence-type-sha256-9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94) | + + + +### `Message[]` + +SHA-256: `fc8242857caf7450d7f68a1f509dce83e237bd21571666006895124cb2246a83` + +[`Message`](#persistence-type-sha256-691c0f641cd3e8072fdacd6fa8c400253cf75a0ce9285d8ce89141bbb24f2fb6) 的数组。 + + + + + + + +### `ModelMessageSource` + +SHA-256: `719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91` + +来源:[`packages/llm/llm/src/message.ts:24`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"model"` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `replayState` | 可选 | `unknown`(不透明) | + + + + + + + +### `ModelSelection` + +SHA-256: `f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b` + +来源:[`packages/api/session-controller/src/types.ts:86`](../packages/api/session-controller/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `reasoningEffort` | 可选 | `string` | + + + + + + + +### `OneShotScheduleDispatchChange` + +SHA-256: `8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af` + +来源:[`packages/schedule/schedule/src/types.ts:86`](../packages/schedule/schedule/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `operation` | 必需 | `"dispatch"` | +| `version` | 必需 | `1` | + + + + + + + +### `OneShotSubagentDescriptorData` + +SHA-256: `5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564` + +来源:[`packages/subagent/subagent/src/descriptor.ts:61`](../packages/subagent/subagent/src/descriptor.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `label` | 可选 | `string` | +| `mode` | 必需 | `"one-shot"` | +| `provider` | 必需 | `string` | +| `version` | 必需 | `number` | + + + + + + + +### `OptionalSessionSeq` + +SHA-256: `3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f` + +来源:[`packages/core/session/src/types.ts:65`](../packages/core/session/src/types.ts) + +以下类型之一: + +- `null` +- `number` + + + + + + + +### `PresentedFile` + +SHA-256: `b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97` + +来源:[`packages/deliverables/tool-present/src/types.ts:5`](../packages/deliverables/tool-present/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `description` | 可选 | `string` | +| `path` | 必需 | `string` | + + + +### `PresentedFile[]` + +SHA-256: `1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345` + +[`PresentedFile`](#persistence-type-sha256-b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97) 的数组。 + + + + + + + +### `PtcDispatchEventData` + +SHA-256: `0ee52de154f8955c7abc82cffebc57452dcc8c44dccbdb6ad16c71a11305ead8` + +来源:[`packages/core/tools/src/types.ts:20`](../packages/core/tools/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `unknown`(不透明) | +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `error` | 可选 | [`{ code, name, reason? }`](#persistence-type-sha256-a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735) | +| `isError` | 必需 | `boolean` | +| `name` | 必需 | `string` | +| `parentCallId` | 必需 | `string` | +| `rootCallId` | 必需 | `string` | +| `subCallId` | 必需 | `string` | + + + + + + + +### `PtcDispatchStartEventData` + +SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f` + +来源:[`packages/core/tools/src/types.ts:11`](../packages/core/tools/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `unknown`(不透明) | +| `name` | 必需 | `string` | +| `parentCallId` | 必需 | `string` | +| `rootCallId` | 必需 | `string` | +| `subCallId` | 必需 | `string` | + + + + + + + +### `ReasoningBlock` + +SHA-256: `814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e` + +来源:[`packages/llm/llm/src/types.ts:68`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `text` | 必需 | `string` | +| `type` | 必需 | `"reasoning"` | + + + + + + + +### `ReplayEnvelope` + +SHA-256: `0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555` + +来源:[`packages/llm/llm/src/types.ts:418`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blocks` | 可选 | [`unknown[]`](#persistence-type-sha256-b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7) | +| `response` | 必需 | `unknown`(不透明) | + + + + + + + +### `RequestContext` + +SHA-256: `b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081` + +来源:[`packages/core/session/src/types.ts:254`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `contextWindow` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `systemPromptUpdate` | 可选 | `"in-history"` | + + + + + + + +### `RequestHeaderReason` + +SHA-256: `530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6` + +来源:[`packages/core/session/src/types.ts:273`](../packages/core/session/src/types.ts) + +以下类型之一: + +- `"change"` +- `"initial"` +- `"resume"` +- `"series"` + + + + + + + +### `SandboxMode` + +SHA-256: `fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd` + +来源:[`packages/sandbox/sandbox/src/index.ts:29`](../packages/sandbox/sandbox/src/index.ts) + +以下类型之一: + +- `"danger-full-access"` +- `"read-only"` +- `"workspace-write"` + + + + + + + +### `ScheduleChange` + +SHA-256: `e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1` + +来源:[`packages/schedule/schedule/src/types.ts:105`](../packages/schedule/schedule/src/types.ts) + +以下类型之一: + +- [`EveryScheduleDispatchChange`](#persistence-type-sha256-e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344) +- [`ScheduleDeleteChange`](#persistence-type-sha256-18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0) +- [`OneShotScheduleDispatchChange`](#persistence-type-sha256-8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af) +- [`ScheduleCreateChange`](#persistence-type-sha256-ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f) + + + + + + + +### `ScheduleCreateChange` + +SHA-256: `ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f` + +来源:[`packages/schedule/schedule/src/types.ts:72`](../packages/schedule/schedule/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `operation` | 必需 | `"create"` | +| `schedule` | 必需 | [`ScheduleRecord`](#persistence-type-sha256-d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87) | +| `version` | 必需 | `1` | + + + + + + + +### `ScheduleDeleteChange` + +SHA-256: `18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0` + +来源:[`packages/schedule/schedule/src/types.ts:79`](../packages/schedule/schedule/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `operation` | 必需 | `"delete"` | +| `version` | 必需 | `1` | + + + + + + + +### `ScheduleRecord` + +SHA-256: `d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87` + +来源:[`packages/schedule/schedule/src/types.ts:69`](../packages/schedule/schedule/src/types.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `after` | 未声明 | `afterSeconds`: `number`; `id`: `string`; `prompt`: `string`; `scheduledAt`: `string` | [`AfterScheduleRecord`](#persistence-type-sha256-27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe) | +| `at` | 未声明 | `id`: `string`; `prompt`: `string`; `scheduledAt`: `string` | [`AtScheduleRecord`](#persistence-type-sha256-658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e) | +| `every` | 未声明 | `everySeconds`: `number`; `id`: `string`; `prompt`: `string`; `scheduledAt`: `string` | [`EveryScheduleRecord`](#persistence-type-sha256-66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14) | + + + + + + + +### `SessionHeader` + +SHA-256: `1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445` + +来源:[`packages/core/session/src/types.ts:94`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentPreset` | 可选 | `string` | +| `createdAt` | 必需 | `number` | +| `cwd` | 可选 | `string` | +| `delegationDepth` | 可选 | `number` | +| `id` | 必需 | `string` | +| `isSeeded` | 必需 | `boolean` | +| `origin` | 可选 | `"subagent"` | +| `parentSession` | 可选 | `string` | +| `version` | 必需 | `4` | + + + + + + + +### `SessionReferenceSource` + +SHA-256: `f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f` + +来源:[`packages/context/session-reference/src/types.ts:13`](../packages/context/session-reference/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"session-reference"` | +| `references` | 必需 | [`{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }[]`](#persistence-type-sha256-df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18) | +| `version` | 必需 | `1` | + + + + + + + +### `SessionTitleEventData` + +SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4` + +来源:[`packages/session/session-title/src/types.ts:41`](../packages/session/session-title/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `messageSeqs` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `source` | 必需 | [`SessionTitleSource`](#persistence-type-sha256-30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f) | +| `title` | 必需 | `string` | + + + + + + + +### `SessionTitleLlmRequestEventData` + +SHA-256: `9bc85364d1f37d9c837db6a3bdd3d1d007d923cdc7401a3322be9f12fdc225fd` + +来源:[`packages/session/session-title-llm/src/index.ts:34`](../packages/session/session-title-llm/src/index.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `maxTokens` | 必需 | `number` | +| `messageSeqs` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `messages` | 必需 | [`Message[]`](#persistence-type-sha256-fc8242857caf7450d7f68a1f509dce83e237bd21571666006895124cb2246a83) | +| `route` | 必需 | [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) | +| `system` | 必需 | `string` | +| `titleProvider` | 必需 | `string` | + + + + + + + + + + + +### `SessionTitleModelIdentity` + +SHA-256: `07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235` + +来源:[`packages/session/session-title/src/types.ts:20`](../packages/session/session-title/src/types.ts) · [`packages/subagent/tool-subagent/src/model-selection.ts:9`](../packages/subagent/tool-subagent/src/model-selection.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | + + + +### `SessionTitleModelIdentity[]` + +SHA-256: `ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec` + +[`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) 的数组。 + + + + + + + +### `SessionTitleSource` + +SHA-256: `30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f` + +来源:[`packages/session/session-title/src/types.ts:28`](../packages/session/session-title/src/types.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `fallback` | 未声明 | 无 | [`{ kind: "fallback" }`](#persistence-type-sha256-1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597) | +| `provider` | 未声明 | `provider`: `string` | [`{ kind: "provider" }`](#persistence-type-sha256-b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812) | +| `user` | 未声明 | 无 | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | + + + + + + + +### `SkillCatalogSource` + +SHA-256: `fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093` + +来源:[`packages/skill/tool-skill/src/index.ts:34`](../packages/skill/tool-skill/src/index.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `entries` | 必需 | [`{ description, name }[]`](#persistence-type-sha256-aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba) | +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"skill-catalog"` | +| `update` | 可选 | `true` | + + + + + + + +### `SkillInvocationSource` + +SHA-256: `672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db` + +来源:[`packages/skill/skill/src/index.ts:146`](../packages/skill/skill/src/index.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"skill-invocation"` | +| `name` | 必需 | `string` | + + + + + + + +### `StreamChunk` + +SHA-256: `47e9095591ae36e7c39ee62553097772f2bfa16304536a72dbbc3f691f605180` + +来源:[`packages/llm/llm/src/types.ts:440`](../packages/llm/llm/src/types.ts) + +以下类型之一: + +- [`{ type: "tool-call-delta" }`](#persistence-type-sha256-88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a) +- [`{ type: "block-end" }`](#persistence-type-sha256-d4b739491689cc6bb13d07ffac1a32239875abda364c0d5edd8f74faf5e9c00d) +- [`{ type: "block-start" }`](#persistence-type-sha256-3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90) +- [`{ type: "reasoning-delta" }`](#persistence-type-sha256-2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095) +- [`{ type: "text-delta" }`](#persistence-type-sha256-95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65) +- [`{ type: "finish" }`](#persistence-type-sha256-a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1) +- [`{ type: "usage" }`](#persistence-type-sha256-f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515) + + + + + + + +### `SubagentCatalogEvent` + +SHA-256: `3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e` + +来源:[`packages/subagent/subagent/src/catalog.ts:24`](../packages/subagent/subagent/src/catalog.ts) + +以下类型之一: + +- [`{ childCreatedAt, childId, label, mode, … }`](#persistence-type-sha256-0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd) +- [`{ childCreatedAt, childId, label?, mode, … }`](#persistence-type-sha256-5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694) + + + + + + + +### `SubagentDescriptorData` + +SHA-256: `86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde` + +来源:[`packages/subagent/subagent/src/descriptor.ts:89`](../packages/subagent/subagent/src/descriptor.ts) + +以下类型之一: + +- [`ContinuableSubagentDescriptorData`](#persistence-type-sha256-6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f) +- [`OneShotSubagentDescriptorData`](#persistence-type-sha256-5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564) + + + + + + + +### `SubagentSettledMessageSource` + +SHA-256: `4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a` + +来源:[`packages/subagent/subagent/src/continuation-messages.ts:30`](../packages/subagent/subagent/src/continuation-messages.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"subagent-settled"` | +| `senderSessionId` | 必需 | `string` | +| `summary` | 必需 | `string` | + + + + + + + +### `SurfaceOp` + +SHA-256: `335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5` + +来源:[`packages/core/session/src/types.ts:462`](../packages/core/session/src/types.ts) + +以下类型之一: + +- `"append"` +- [`{ endSeq, op, startSeq }`](#persistence-type-sha256-bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825) + + + + + + + +### `SystemMessage` + +SHA-256: `09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363` + +来源:[`packages/llm/llm/src/message.ts:151`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"system"` | +| `source` | 必需 | [`SystemPromptMessageSource`](#persistence-type-sha256-65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad) | + + + + + + + +### `SystemPromptMessageSource` + +SHA-256: `65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad` + +来源:[`packages/llm/llm/src/message.ts:35`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"system-prompt"` | + + + + + + + +### `TeamMemberPhase` + +SHA-256: `dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd` + +来源:[`packages/experimental/agent-team/src/types.ts:44`](../packages/experimental/agent-team/src/types.ts) + +以下类型之一: + +- `"active"` +- `"failed"` +- `"provisioning"` + + + + + + + +### `TeamMemberSnapshot` + +SHA-256: `6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25` + +来源:[`packages/experimental/agent-team/src/types.ts:47`](../packages/experimental/agent-team/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `context` | 必需 | [`union (2 variants)`](#persistence-type-sha256-50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48) | +| `description` | 必需 | `string` | +| `error` | 可选 | `string` | +| `id` | 必需 | `string` | +| `name` | 必需 | `string` | +| `phase` | 必需 | [`TeamMemberPhase`](#persistence-type-sha256-dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd) | +| `provider` | 必需 | `string` | + + + + + + + +### `TeamMessageSnapshot` + +SHA-256: `2eafefdc6f79a4922d68a787a09eaf4dd2b2369c3777fba4c05e800b5678ac8e` + +来源:[`packages/experimental/agent-team/src/types.ts:106`](../packages/experimental/agent-team/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | 必需 | `string` | +| `senderId` | 必需 | `string` | +| `senderName` | 必需 | `string` | +| `targetId` | 必需 | `string` | + + + + + + + +### `TeamMessageSource` + +SHA-256: `2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0` + +来源:[`packages/experimental/agent-team/src/types.ts:115`](../packages/experimental/agent-team/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"team-message"` | +| `messageId` | 必需 | `string` | +| `senderId` | 必需 | `string` | +| `senderName` | 必需 | `string` | +| `teamId` | 必需 | `string` | + + + + + + + +### `TeamTaskSnapshot` + +SHA-256: `51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357` + +来源:[`packages/experimental/agent-team/src/types.ts:74`](../packages/experimental/agent-team/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blockedBy` | 必需 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `description` | 必需 | `string` | +| `id` | 必需 | `string` | +| `ownerId` | 可选 | `string` | +| `revision` | 必需 | `number` | +| `status` | 必需 | [`TeamTaskStatus`](#persistence-type-sha256-b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943) | +| `subject` | 必需 | `string` | +| `writeScopes` | 必需 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | + + + + + + + +### `TeamTaskStatus` + +SHA-256: `b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943` + +来源:[`packages/experimental/agent-team/src/types.ts:71`](../packages/experimental/agent-team/src/types.ts) + +以下类型之一: + +- `"completed"` +- `"deleted"` +- `"in_progress"` +- `"pending"` + + + + + + + +### `TextBlock` + +SHA-256: `4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c` + +来源:[`packages/llm/llm/src/types.ts:62`](../packages/llm/llm/src/types.ts) · [`packages/web/web-search-deepseek/src/provider.ts:66`](../packages/web/web-search-deepseek/src/provider.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `text` | 必需 | `string` | +| `type` | 必需 | `"text"` | + + + + + + + +### `TodoItem` + +SHA-256: `a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a` + +来源:[`packages/todo/tool-todo/src/types.ts:21`](../packages/todo/tool-todo/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | `string` | +| `status` | 必需 | [`union (3 variants)`](#persistence-type-sha256-fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4) | + + + +### `TodoItem[]` + +SHA-256: `4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea` + +[`TodoItem`](#persistence-type-sha256-a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a) 的数组。 + + + + + + + +### `TokenUsage` + +SHA-256: `fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394` + +来源:[`packages/llm/llm/src/types.ts:176`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `cacheReadTokens` | 可选 | `number` | +| `cacheWriteTokens` | 可选 | `number` | +| `inputTokens` | 必需 | `number` | +| `outputTokens` | 必需 | `number` | +| `reasoningTokens` | 可选 | `number` | +| `totalTokens` | 可选 | `number` | + + + + + + + +### `ToolAdditionBlock` + +SHA-256: `8e611bf46821e5003a1605a73560a6f56388295149d449dfe2142d5ec335f29c` + +来源:[`packages/llm/llm/src/types.ts:115`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `tool` | 可选 | `never` | +| `toolName` | 必需 | `string` | +| `type` | 必需 | `"tool-addition"` | + + + + + + + +### `ToolCallBlock` + +SHA-256: `c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea` + +来源:[`packages/llm/llm/src/types.ts:105`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `string` | +| `id` | 必需 | `string` | +| `name` | 必需 | `string` | +| `type` | 必需 | `"tool-call"` | + + + + + + + +### `ToolMessageSource` + +SHA-256: `d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab` + +来源:[`packages/llm/llm/src/message.ts:29`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `callId` | 必需 | `string` | +| `kind` | 必需 | `"tool"` | + + + + + + + +### `ToolRemovalBlock` + +SHA-256: `43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8` + +来源:[`packages/llm/llm/src/types.ts:127`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `toolName` | 必需 | `string` | +| `type` | 必需 | `"tool-removal"` | + + + + + + + +### `ToolRestriction` + +SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f` + +来源:[`packages/core/tools/src/index.ts:689`](../packages/core/tools/src/index.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `allow` | 可选 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `deny` | 可选 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | + + + + + + + +### `ToolResultMessage` + +SHA-256: `4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731` + +来源:[`packages/llm/llm/src/message.ts:173`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | 必需 | `string` | +| `isError` | 可选 | `boolean` | +| `role` | 必需 | `"tool"` | +| `source` | 必需 | [`ToolMessageSource`](#persistence-type-sha256-d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab) | +| `toolCallId` | 必需 | `string` | + + + + + + + +### `ToolSchema` + +SHA-256: `66ba70f6f068da443f969a0b947a013c3addd776b9b60a0a393759c19825e9a2` + +来源:[`packages/llm/llm/src/types.ts:461`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `deferLoading` | 可选 | `true` | +| `description` | 必需 | `string` | +| `name` | 必需 | `string` | +| `parameters` | 必需 | [`{}`](#persistence-type-sha256-0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f) | + + + +### `ToolSchema[]` + +SHA-256: `a0baff42eb900561f91032b6950a3925cf19c5c8d9ba33948ac69e4ac7dee573` + +[`ToolSchema`](#persistence-type-sha256-66ba70f6f068da443f969a0b947a013c3addd776b9b60a0a393759c19825e9a2) 的数组。 + + + + + + + +### `ToolWorkflowAgentEndData` + +SHA-256: `c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7` + +来源:[`packages/workflow/tool-workflow/src/types.ts:29`](../packages/workflow/tool-workflow/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `outcome` | 必需 | [`WorkflowAgentOutcome`](#persistence-type-sha256-c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896) | +| `runId` | 必需 | `string` | +| `seq` | 必需 | `number` | + + + + + + + +### `ToolWorkflowAgentStartData` + +SHA-256: `9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc` + +来源:[`packages/workflow/tool-workflow/src/types.ts:20`](../packages/workflow/tool-workflow/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `childId` | 必需 | `string` | +| `label` | 必需 | `string` | +| `phase` | 可选 | `string` | +| `runId` | 必需 | `string` | +| `seq` | 必需 | `number` | + + + + + + + +### `ToolWorkflowRunEndData` + +SHA-256: `7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462` + +来源:[`packages/workflow/tool-workflow/src/types.ts:36`](../packages/workflow/tool-workflow/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `runId` | 必需 | `string` | +| `stopReason` | 必需 | [`WorkflowStopReason`](#persistence-type-sha256-8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15) | + + + + + + + +### `ToolWorkflowRunStartData` + +SHA-256: `a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c` + +来源:[`packages/workflow/tool-workflow/src/types.ts:14`](../packages/workflow/tool-workflow/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `name` | 必需 | `string` | +| `runId` | 必需 | `string` | + + + + + + + +### `TurnEndCancelCause` + +SHA-256: `1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0` + +来源:[`packages/core/session/src/types.ts:196`](../packages/core/session/src/types.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `disposed` | 未声明 | 无 | [`{ kind: "disposed" }`](#persistence-type-sha256-4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db) | +| `hook` | 未声明 | `reason`: `string` | [`{ kind: "hook" }`](#persistence-type-sha256-6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d) | +| `legacy` | 未声明 | 无 | [`{ kind: "legacy" }`](#persistence-type-sha256-eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c) | +| `parent` | 未声明 | 无 | [`{ kind: "parent" }`](#persistence-type-sha256-6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800) | +| `user` | 未声明 | 无 | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | + + + + + + + +### `TurnEndReason` + +SHA-256: `f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402` + +来源:[`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts) + +| kind | form 属性 | 其他必需字段 | 完整定义 | +|---|---|---|---| +| `aborted` | 未声明 | `reason`: [`TurnEndCancelCause`](#persistence-type-sha256-1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0) | [`{ kind: "aborted", reason }`](#persistence-type-sha256-0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3) | +| `blocked` | 未声明 | 无 | [`{ kind: "blocked" }`](#persistence-type-sha256-023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4) | +| `completed` | 未声明 | 无 | [`{ kind: "completed" }`](#persistence-type-sha256-b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0) | +| `error` | 未声明 | `error`: [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | [`{ error, kind: "error" }`](#persistence-type-sha256-79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985) | +| `forked` | 未声明 | 无 | [`{ kind: "forked" }`](#persistence-type-sha256-ec8b5ff7c77ca6893ac7ba5a0c5b2aefeb52f12c64450b7359660c2a7e8a53d7) | +| `interrupted` | 未声明 | 无 | [`{ kind: "interrupted" }`](#persistence-type-sha256-56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23) | +| `max-tokens` | 未声明 | 无 | [`{ kind: "max-tokens" }`](#persistence-type-sha256-ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7) | + + + + + + + +### `UserMessage` + +SHA-256: `64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586` + +来源:[`packages/llm/llm/src/message.ts:162`](../packages/llm/llm/src/message.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"user"` | +| `source` | 必需 | [`MessageSource`](#persistence-type-sha256-40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945) | + +消息源兼容策略:`source` — `session-source-attribution` v1; `session.user-message.source`; `kind`; `preserve`. + +仅表示归属的新增 kind:`tmux-context`. + + + +### `UserMessage[]` + +SHA-256: `d1f27cf1650e5f59d5d6e95ce6dfd92b31757af076a8ab6418a70b6dbdd53621` + +[`UserMessage`](#persistence-type-sha256-64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586) 的数组。 + + + + + + + +### `WorkflowAgentOutcome` + +SHA-256: `c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896` + +来源:[`packages/workflow/workflow/src/types.ts:110`](../packages/workflow/workflow/src/types.ts) + +以下类型之一: + +- `"cancelled"` +- `"completed"` +- `"failed"` + + + + + + + +### `WorkflowStopReason` + +SHA-256: `8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15` + +来源:[`packages/workflow/workflow/src/types.ts:63`](../packages/workflow/workflow/src/types.ts) + +以下类型之一: + +- `"cancelled"` +- `"completed"` +- `"error"` + + + +### `boolean` + +SHA-256: `aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877` + +`boolean` + + + +### `false` + +SHA-256: `0c4205180f75b9ee1e0d878bd9a9851628b5dc18448486389d9c5fdc3f1ccda3` + +`false` + + + +### `never` + +SHA-256: `fcf427290c6213c2a7feb57492d832ce324f5b9737a759f424dab69e6bd101a0` + +`never` + + + +### `null` + +SHA-256: `938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615` + +`null` + + + + + + + +### `number` + +SHA-256: `0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7` + +来源:[`packages/core/session/src/types.ts:32`](../packages/core/session/src/types.ts) + +`number` + + + +### `number[]` + +SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` + +`number` 的数组。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +### `string` + +SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` + +来源:[`packages/api/session-controller/src/types.ts:380`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:20`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:10`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/webhook/webhook/src/brand.ts:12`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:6`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:9`](../packages/webhook/webhook/src/brand.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) + +`string` + + + +### `string[]` + +SHA-256: `93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2` + +`string` 的数组。 + + + +### `true` + +SHA-256: `dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521` + +`true` + + + +### `tuple (1 positions)` + +SHA-256: `4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`{ type: "web_search_20250305" }`](#persistence-type-sha256-2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3) | + + + +### `tuple (1 positions)` + +SHA-256: `8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`TextBlock`](#persistence-type-sha256-4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c) | + + + +### `tuple (1 positions)` + +SHA-256: `b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`{ role: "user" }`](#persistence-type-sha256-9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5) | + + + +### `union (2 variants)` + +SHA-256: `1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92` + +以下类型之一: + +- `"error"` +- `"success"` + + + +### `union (2 variants)` + +SHA-256: `50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48` + +以下类型之一: + +- `"fork"` +- `"fresh"` + + + +### `union (2 variants)` + +SHA-256: `9947aa5938fe19a895298da412917acbf9ffb5093a73ab8baa257e6ae9e63a07` + +以下类型之一: + +- [`{ compactionId, llmStreamCall, maxTokens?, model, … }`](#persistence-type-sha256-a99ec0993c62c058e50af9f68922202a3b54f5e259bc2abf1915a73381d2316d) +- [`{ compactionId, maxTokens?, model, provider, … }`](#persistence-type-sha256-576a2de8355eb09850963ff5953420b172e274d9283666eb7d889097db120796) + + + + + +### `union (3 variants)` + +SHA-256: `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` + +以下类型之一: + +- [`{ ignorable?, seq, sourceEventSeqs?, surfaceOp, … }`](#persistence-type-sha256-998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0) +- [`{ ignorable?, seq, surfaceOp, time, … }`](#persistence-type-sha256-7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb) +- [`{ ignorable?, seq, time, type }`](#persistence-type-sha256-e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f) + + + +### `union (3 variants)` SHA-256: `904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd` @@ -1868,832 +5415,36 @@ SHA-256: `904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd` - `"replace"` - `"set"` - + -### `event:agent/inbox/spliced.data.inserted[0].source[17].entries` +### `union (3 variants)` -SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` - -[`event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]`](#persistence-type-eventagentinboxspliceddatainserted0source17entries0) 的数组。 - - - -### `event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]` - -SHA-256: `83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693` - -来源:[`packages/skill/tool-skill/src/index.ts:40`](../packages/skill/tool-skill/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `description` | 必需 | `string` | -| `name` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[19]` - -SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` - -来源:[`packages/webhook/webhook/src/types.ts:74`](../packages/webhook/webhook/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `deliveryId` | 必需 | `string` | -| `form` | 必需 | `"notice"` | -| `kind` | 必需 | `"webhook"` | -| `provider` | 必需 | `string` | -| `ruleId` | 必需 | `string` | -| `source` | 必需 | `string` | -| `summary` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[2]` - -SHA-256: `dda6e111a8ccfc12f6e742e977a1a4e3549e8c03732a5ff6c8d7c3d4bcb7a412` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"instructions"` | -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[3]` - -SHA-256: `2f90a7b3646fea3e677bd7b4000aa96f3b8964f107b614e204e11ad4051c24fc` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"catalog"` | -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[4]` - -SHA-256: `e8d26e6993445743e6c4342c31b284c7d8f5574369abdd6021183af1a6b3538f` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"snapshot"` | -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | -| `sections` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[4].sections`](#persistence-type-eventagentinboxspliceddatainserted0source4sections) | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[4].sections` - -SHA-256: `c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262` - -[`packages/llm/llm/src/message.ts#ContextSnapshotSection`](#persistence-type-packagesllmllmsrcmessagetscontextsnapshotsection) 的数组。 - - - -### `event:agent/inbox/spliced.data.inserted[0].source[5]` - -SHA-256: `b4d298d90c798fa4d1f5b030ce3ce8031c4c41beafdb05323bec8b2a06903b43` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"notice"` | -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | -| `summary` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[6]` - -SHA-256: `2ce7ef3b3daebf95815c7ae454a751d3e67ca7a22e2e0734fe2942df393bb66c` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"relay"` | -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | - - - -### `event:agent/inbox/spliced.data.inserted[0].source[7]` - -SHA-256: `85e1bd563d6c80c1f377f99f91103fec4e315148a7330f3b3dae7c2d04e33b01` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"recall"` | -| `kind` | 必需 | `"plugin"` | -| `plugin` | 必需 | `string` | - - - -### `event:approval/asked` - -SHA-256: `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:approval/asked.data`](#persistence-type-eventapprovalaskeddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"approval/asked"` | - - - -### `event:approval/asked.data` - -SHA-256: `45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448` - -来源:[`packages/interaction/user-approval/src/types.ts:44`](../packages/interaction/user-approval/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `callId` | 可选 | `string` | -| `id` | 必需 | `string` | -| `reason` | 可选 | `string` | -| `toolName` | 必需 | `string` | - - - -### `event:approval/decided` - -SHA-256: `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:approval/decided.data`](#persistence-type-eventapprovaldecideddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"approval/decided"` | - - - -### `event:approval/decided.data` - -SHA-256: `93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9` - -来源:[`packages/interaction/user-approval/src/types.ts:55`](../packages/interaction/user-approval/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `id` | 必需 | `string` | -| `outcome` | 必需 | [`packages/interaction/user-approval/src/types.ts#ApprovalOutcome`](#persistence-type-packagesinteractionuser-approvalsrctypestsapprovaloutcome) | - - - -### `event:approval/policy` - -SHA-256: `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:approval/policy.data`](#persistence-type-eventapprovalpolicydata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"approval/policy"` | - - - -### `event:approval/policy.data` - -SHA-256: `11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912` - -来源:[`packages/interaction/user-approval/src/index.ts:33`](../packages/interaction/user-approval/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `policy` | 必需 | [`packages/interaction/user-approval/src/index.ts#ApprovalPolicy`](#persistence-type-packagesinteractionuser-approvalsrcindextsapprovalpolicy) | -| `source` | 可选 | `"delegation"` | - - - -### `event:assistant/attempt` - -SHA-256: `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:assistant/attempt.data`](#persistence-type-eventassistantattemptdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"assistant/attempt"` | - - - -### `event:assistant/attempt.data` - -SHA-256: `0c6412d3ba5e41adfaa6929c7d4093f2d52d8598c03f35844fc0d55e3070a3b1` - -来源:[`packages/core/session/src/types.ts:335`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `step` | 必需 | `number` | -| `stream` | 必需 | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | -| `turn` | 必需 | `number` | - - - -### `event:assistant/attempt.data.stream` - -SHA-256: `26f3bb7529cfce1e3a0f1ededa365d8b426758ca0feeb0beabeee805f8bb8346` - -[`packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord`](#persistence-type-packagesllmllmsrcassistant-streamtsassistantstreamrecord) 的数组。 - - - -### `event:assistant/attempt.data.stream[0][0]` - -SHA-256: `e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33` - -来源:[`packages/llm/llm/src/assistant-stream.ts:21`](../packages/llm/llm/src/assistant-stream.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `dt` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `index` | 必需 | `number` | -| `texts` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `time0` | 必需 | `number` | -| `type` | 必需 | `"text-chunks"` | - - - -### `event:assistant/attempt.data.stream[0][0].texts` - -SHA-256: `93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2` - -`string` 的数组。 - - - -### `event:assistant/attempt.data.stream[0][1]` - -SHA-256: `71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd` - -来源:[`packages/llm/llm/src/assistant-stream.ts:28`](../packages/llm/llm/src/assistant-stream.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `dt` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `index` | 必需 | `number` | -| `texts` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `time0` | 必需 | `number` | -| `type` | 必需 | `"reasoning-chunks"` | - - - -### `event:assistant/attempt.data.stream[0][2]` - -SHA-256: `3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6` - -来源:[`packages/llm/llm/src/assistant-stream.ts:35`](../packages/llm/llm/src/assistant-stream.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `args` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `dt` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `id` | 必需 | `string` | -| `index` | 必需 | `number` | -| `name` | 可选 | `string` | -| `time0` | 必需 | `number` | -| `type` | 必需 | `"tool-call-chunks"` | - - - -### `event:assistant/attempt.data.stream[0][3]` - -SHA-256: `c93b6f51b399607349b4bcc66b58e848a44250ffc1e2537207bd092dfff94192` - -来源:[`packages/llm/llm/src/assistant-stream.ts:44`](../packages/llm/llm/src/assistant-stream.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `chunk` | 必需 | [`packages/llm/llm/src/types.ts#StreamChunk`](#persistence-type-packagesllmllmsrctypestsstreamchunk) | -| `time` | 必需 | `number` | -| `type` | 必需 | `"chunk"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[0]` - -SHA-256: `647cb2e3aeb58e27d1d4d60011f208bb66dce257e8654193c533b47c4c22c253` - -来源:[`packages/llm/llm/src/types.ts:427`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `blockType` | 必需 | [`packages/llm/llm/src/types.ts#ContentBlockType`](#persistence-type-packagesllmllmsrctypestscontentblocktype) | -| `index` | 必需 | `number` | -| `type` | 必需 | `"block-start"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[1]` - -SHA-256: `95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65` - -来源:[`packages/llm/llm/src/types.ts:428`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `index` | 必需 | `number` | -| `text` | 必需 | `string` | -| `type` | 必需 | `"text-delta"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[2]` - -SHA-256: `2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095` - -来源:[`packages/llm/llm/src/types.ts:429`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `index` | 必需 | `number` | -| `text` | 必需 | `string` | -| `type` | 必需 | `"reasoning-delta"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[3]` - -SHA-256: `88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a` - -来源:[`packages/llm/llm/src/types.ts:430`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `argumentsDelta` | 必需 | `string` | -| `id` | 必需 | `string` | -| `index` | 必需 | `number` | -| `name` | 可选 | `string` | -| `type` | 必需 | `"tool-call-delta"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[4]` - -SHA-256: `90c811b8c2668898515e69a24e82caffeb08517f9c7aa193867ff0380f3b535d` - -来源:[`packages/llm/llm/src/types.ts:431`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `block` | 必需 | [`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock) | -| `index` | 必需 | `number` | -| `type` | 必需 | `"block-end"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[5]` - -SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515` - -来源:[`packages/llm/llm/src/types.ts:432`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `type` | 必需 | `"usage"` | -| `usage` | 必需 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6]` - -SHA-256: `a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1` - -来源:[`packages/llm/llm/src/types.ts:433`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `reason` | 必需 | [`packages/llm/llm/src/types.ts#FinishReason`](#persistence-type-packagesllmllmsrctypestsfinishreason) | -| `replayState` | 可选 | [`packages/llm/llm/src/types.ts#ReplayEnvelope`](#persistence-type-packagesllmllmsrctypestsreplayenvelope) | -| `type` | 必需 | `"finish"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]` - -SHA-256: `8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0` - -来源:[`packages/llm/llm/src/types.ts:147`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | -| `kind` | 必需 | `"aborted"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]` - -SHA-256: `693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057` - -来源:[`packages/llm/llm/src/types.ts:148`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | -| `kind` | 必需 | `"error"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]` - -SHA-256: `ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7` - -来源:[`packages/core/session/src/types.ts:213`](../packages/core/session/src/types.ts) · [`packages/llm/llm/src/types.ts:146`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"max-tokens"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]` - -SHA-256: `1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f` - -来源:[`packages/llm/llm/src/types.ts:144`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"stop"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]` - -SHA-256: `287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a` - -来源:[`packages/llm/llm/src/types.ts:145`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"tool-calls"` | - - - -### `event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks` - -SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7` - -`unknown`(不透明) 的数组。 - - - -### `event:assistant/message` - -SHA-256: `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:assistant/message.data`](#persistence-type-eventassistantmessagedata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | 必需 | `number` | -| `type` | 必需 | `"assistant/message"` | - - - -### `event:assistant/message.data` - -SHA-256: `77b8491f946edfc8cc77ebae3ba49183759da31ba2dfa83d4c9e9e618c4b91d2` - -来源:[`packages/core/session/src/types.ts:321`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `interrupted` | 可选 | `true` | -| `message` | 必需 | [`packages/llm/llm/src/message.ts#AssistantMessage`](#persistence-type-packagesllmllmsrcmessagetsassistantmessage) | -| `step` | 必需 | `number` | -| `stream` | 必需 | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | -| `turn` | 必需 | `number` | -| `usage` | 可选 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:command/done` - -SHA-256: `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:command/done.data`](#persistence-type-eventcommanddonedata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"command/done"` | - - - -### `event:command/done.data` - -SHA-256: `5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51` - -来源:[`packages/interaction/commands/src/types.ts:112`](../packages/interaction/commands/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `commandId` | 必需 | `string` | -| `kind` | 必需 | [`event:command/done.data.kind`](#persistence-type-eventcommanddonedatakind) | -| `sourceEventSeq` | 可选 | `number` | -| `text` | 可选 | `string` | - - - -### `event:command/done.data.kind` - -SHA-256: `1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92` +SHA-256: `fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4` 以下类型之一: -- `"error"` -- `"success"` +- `"completed"` +- `"in_progress"` +- `"pending"` - + -### `event:command/run` +### `union (6 variants)` -SHA-256: `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:command/run.data`](#persistence-type-eventcommandrundata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"command/run"` | - - - -### `event:command/run.data` - -SHA-256: `a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86` - -来源:[`packages/interaction/commands/src/types.ts:105`](../packages/interaction/commands/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `args` | 可选 | `string` | -| `commandId` | 必需 | `string` | -| `name` | 必需 | `string` | -| `source` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) | - - - -### `event:compaction/end` - -SHA-256: `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:compaction/end.data`](#persistence-type-eventcompactionenddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"compaction/end"` | - - - -### `event:compaction/end.data` - -SHA-256: `ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2` - -来源:[`packages/compaction/compaction/src/types.ts:72`](../packages/compaction/compaction/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `compactionId` | 必需 | `string` | -| `error` | 可选 | `string` | -| `sourceCommandId` | 可选 | `string` | -| `turn` | 必需 | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | - - - -### `event:compaction/end.data.turn` - -SHA-256: `3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f` - -来源:[`packages/core/session/src/types.ts:64`](../packages/core/session/src/types.ts) +SHA-256: `62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379` 以下类型之一: -- `null` -- `number` +- `"block"` +- `"complete"` +- `"create"` +- `"edit"` +- `"pause"` +- `"resume"` - + -### `event:compaction/prune` - -SHA-256: `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:compaction/prune.data`](#persistence-type-eventcompactionprunedata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"compaction/prune"` | - - - -### `event:compaction/prune.data` - -SHA-256: `5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438` - -来源:[`packages/compaction/compaction/src/types.ts:82`](../packages/compaction/compaction/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `shadowedRange` | 必需 | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | -| `shadowedSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `shadowedTokenCount` | 必需 | `number` | - - - -### `event:compaction/prune.data.shadowedRange` - -SHA-256: `9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2` - -来源:[`packages/compaction/compaction/src/types.ts:38`](../packages/compaction/compaction/src/types.ts) · [`packages/compaction/compaction/src/types.ts:84`](../packages/compaction/compaction/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `end` | 必需 | `number` | -| `start` | 必需 | `number` | - - - -### `event:compaction/start` - -SHA-256: `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:compaction/start.data`](#persistence-type-eventcompactionstartdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"compaction/start"` | - - - -### `event:compaction/start.data` - -SHA-256: `3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f` - -来源:[`packages/compaction/compaction/src/types.ts:24`](../packages/compaction/compaction/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `compactionId` | 必需 | `string` | -| `sourceCommandId` | 可选 | `string` | -| `turn` | 必需 | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | - - - -### `event:compaction/summary` - -SHA-256: `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:compaction/summary.data`](#persistence-type-eventcompactionsummarydata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"compaction/summary"` | - - - -### `event:compaction/summary.data` - -SHA-256: `feb329074f0206ecc06d8a1aa0a0b3e2f47fd27524ba020fbc849ba63e938896` - -以下类型之一: - -- [`event:compaction/summary.data[0]`](#persistence-type-eventcompactionsummarydata0) -- [`event:compaction/summary.data[1]`](#persistence-type-eventcompactionsummarydata1) - - - -### `event:compaction/summary.data[0]` - -SHA-256: `9ff2ad8dddb836f75e8f6197fff2371323dfc396c3c6fb667e6e0b42fda79a5c` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `compactionId` | 必需 | `string` | -| `llmStreamCall` | 必需 | `true` | -| `maxTokens` | 可选 | `number` | -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | -| `rawOutput` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `shadowedRange` | 必需 | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | -| `shadowedSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `shadowedTokenCount` | 必需 | `number` | -| `sourceCommandId` | 可选 | `string` | -| `summary` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `usage` | 可选 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:compaction/summary.data[1]` - -SHA-256: `3aa261c8516b5c955ed12080e6257a56cbe513f6c9f0ac9274c12e96c196ebca` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `compactionId` | 必需 | `string` | -| `maxTokens` | 可选 | `number` | -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | -| `rawOutput` | 可选 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `shadowedRange` | 必需 | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | -| `shadowedSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `shadowedTokenCount` | 必需 | `number` | -| `sourceCommandId` | 可选 | `string` | -| `summary` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `usage` | 可选 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | - - - -### `event:deliverables/presented` - -SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:deliverables/presented.data`](#persistence-type-eventdeliverablespresenteddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"deliverables/presented"` | - - - -### `event:deliverables/presented.data` - -SHA-256: `1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c` - -来源:[`packages/deliverables/tool-present/src/types.ts:15`](../packages/deliverables/tool-present/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `callId` | 必需 | `string` | -| `files` | 必需 | [`event:deliverables/presented.data.files`](#persistence-type-eventdeliverablespresenteddatafiles) | -| `turn` | 必需 | `number` | - - - -### `event:deliverables/presented.data.files` - -SHA-256: `1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345` - -[`packages/deliverables/tool-present/src/types.ts#PresentedFile`](#persistence-type-packagesdeliverablestool-presentsrctypestspresentedfile) 的数组。 - - - -### `event:feedback/message-delete` - -SHA-256: `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackdelete) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"feedback/message-delete"` | - - - -### `event:feedback/message-put` - -SHA-256: `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackput) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"feedback/message-put"` | - - - -### `event:feedback/message-put.data.item.category` +### `union (7 variants)` SHA-256: `3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd` @@ -2707,96 +5458,278 @@ SHA-256: `3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd` - `"service-stability"` - `"task-result"` - + -### `event:feedback/record` +### `unknown` -SHA-256: `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` +SHA-256: `bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d` + +`unknown`:此声明未暴露存储值的内部字段。 + + + +### `unknown[]` + +SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7` + +`unknown`(不透明) 的数组。 + + + +### `{ active }` + +SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5` + +来源:[`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/feedback/command-feedback/src/types.ts#FeedbackRecord`](#persistence-type-packagesfeedbackcommand-feedbacksrctypestsfeedbackrecord) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"feedback/record"` | +| `active` | 必需 | `boolean` | - + -### `event:goal/change` +### `{ agentPreset }` -SHA-256: `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` +SHA-256: `6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406` + +来源:[`packages/preset/agent-presets/src/session.ts:28`](../packages/preset/agent-presets/src/session.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/goal/goal/src/domain.ts#GoalChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalchangemeta) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"goal/change"` | +| `agentPreset` | 必需 | `string` | - + -### `event:goal/change.data[0].operation` +### `{ allowedModels }` -SHA-256: `62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379` +SHA-256: `0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f` -以下类型之一: - -- `"block"` -- `"complete"` -- `"create"` -- `"edit"` -- `"pause"` -- `"resume"` - - - -### `event:hook/invoked` - -SHA-256: `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` +来源:[`packages/subagent/tool-subagent/src/model-selection-state.ts:17`](../packages/subagent/tool-subagent/src/model-selection-state.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:hook/invoked.data`](#persistence-type-eventhookinvokeddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"hook/invoked"` | +| `allowedModels` | 必需 | [`SessionTitleModelIdentity[]`](#persistence-type-sha256-ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec) | - + -### `event:hook/invoked.data` +### `{ args?, commandId, name, source }` -SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` +SHA-256: `a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86` -来源:[`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) +来源:[`packages/interaction/commands/src/types.ts:105`](../packages/interaction/commands/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `dialect` | 必需 | [`packages/hooks/hook-protocol/src/types.ts#HookDialect`](#persistence-type-packageshookshook-protocolsrctypestshookdialect) | -| `handlerId` | 必需 | `string` | -| `matcher` | 可选 | `string` | -| `point` | 必需 | `string` | +| `args` | 可选 | `string` | +| `commandId` | 必需 | `string` | +| `name` | 必需 | `string` | +| `source` | 必需 | [`CommandSource`](#persistence-type-sha256-ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05) | + + + +### `{ arguments, callId, name, step, … }` + +SHA-256: `e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1` + +来源:[`packages/core/session/src/types.ts:361`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `string` | +| `callId` | 必需 | `string` | +| `name` | 必需 | `string` | +| `step` | 必需 | `number` | | `turn` | 必需 | `number` | - + -### `event:hook/result` +### `{ callId, files, turn }` -SHA-256: `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` +SHA-256: `1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c` + +来源:[`packages/deliverables/tool-present/src/types.ts:15`](../packages/deliverables/tool-present/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:hook/result.data`](#persistence-type-eventhookresultdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"hook/result"` | +| `callId` | 必需 | `string` | +| `files` | 必需 | [`PresentedFile[]`](#persistence-type-sha256-1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345) | +| `turn` | 必需 | `number` | - + -### `event:hook/result.data` +### `{ callId?, id, reason?, toolName }` + +SHA-256: `45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448` + +来源:[`packages/interaction/user-approval/src/types.ts:44`](../packages/interaction/user-approval/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `callId` | 可选 | `string` | +| `id` | 必需 | `string` | +| `reason` | 可选 | `string` | +| `toolName` | 必需 | `string` | + + + +### `{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }` + +SHA-256: `4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4` + +来源:[`packages/context/session-reference/src/types.ts:18`](../packages/context/session-reference/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `capturedFormatVersion` | 可选 | `number` | +| `capturedThroughSeq` | 必需 | [`OptionalSessionSeq`](#persistence-type-sha256-3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f) | +| `compacted` | 必需 | `boolean` | +| `inputIndex` | 必需 | `number` | +| `label` | 必需 | `string` | +| `omittedBytes` | 必需 | `number` | +| `omittedMessages` | 必需 | `number` | +| `originalMessages` | 必需 | `number` | +| `retainedMessages` | 必需 | `number` | +| `sessionId` | 必需 | `string` | +| `truncated` | 必需 | `boolean` | + + + +### `{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }[]` + +SHA-256: `df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18` + +[`{ capturedFormatVersion?, capturedThroughSeq, compacted, inputIndex, … }`](#persistence-type-sha256-4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4) 的数组。 + + + +### `{ childCreatedAt, childId, label, mode, … }` + +SHA-256: `0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `childCreatedAt` | 必需 | `number` | +| `childId` | 必需 | `string` | +| `label` | 必需 | `string` | +| `mode` | 必需 | `"continuable"` | +| `version` | 必需 | `0` | + + + +### `{ childCreatedAt, childId, label?, mode, … }` + +SHA-256: `5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `childCreatedAt` | 必需 | `number` | +| `childId` | 必需 | `string` | +| `label` | 可选 | `string` | +| `mode` | 必需 | `"one-shot"` | +| `version` | 必需 | `0` | + + + +### `{ code, name, reason? }` + +SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735` + +来源:[`packages/core/session/src/types.ts:383`](../packages/core/session/src/types.ts) · [`packages/core/tools/src/types.ts:24`](../packages/core/tools/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `code` | 必需 | `string` | +| `name` | 必需 | `string` | +| `reason` | 可选 | `string` | + + + +### `{ commandId, kind, sourceEventSeq?, text? }` + +SHA-256: `5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51` + +来源:[`packages/interaction/commands/src/types.ts:112`](../packages/interaction/commands/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `commandId` | 必需 | `string` | +| `kind` | 必需 | [`union (2 variants)`](#persistence-type-sha256-1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92) | +| `sourceEventSeq` | 可选 | `number` | +| `text` | 可选 | `string` | + + + +### `{ compactionId, error?, sourceCommandId?, turn }` + +SHA-256: `ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2` + +来源:[`packages/compaction/compaction/src/types.ts:72`](../packages/compaction/compaction/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `error` | 可选 | `string` | +| `sourceCommandId` | 可选 | `string` | +| `turn` | 必需 | [`OptionalSessionSeq`](#persistence-type-sha256-3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f) | + + + +### `{ compactionId, llmStreamCall, maxTokens?, model, … }` + +SHA-256: `a99ec0993c62c058e50af9f68922202a3b54f5e259bc2abf1915a73381d2316d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `llmStreamCall` | 必需 | `true` | +| `maxTokens` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `rawOutput` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `shadowedRange` | 必需 | [`{ end, start }`](#persistence-type-sha256-9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2) | +| `shadowedSeqs` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `shadowedTokenCount` | 必需 | `number` | +| `sourceCommandId` | 可选 | `string` | +| `summary` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `usage` | 可选 | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | + + + +### `{ compactionId, maxTokens?, model, provider, … }` + +SHA-256: `576a2de8355eb09850963ff5953420b172e274d9283666eb7d889097db120796` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `maxTokens` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `rawOutput` | 可选 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `shadowedRange` | 必需 | [`{ end, start }`](#persistence-type-sha256-9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2) | +| `shadowedSeqs` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `shadowedTokenCount` | 必需 | `number` | +| `sourceCommandId` | 可选 | `string` | +| `summary` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) | +| `usage` | 可选 | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | + + + +### `{ compactionId, sourceCommandId?, turn }` + +SHA-256: `3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f` + +来源:[`packages/compaction/compaction/src/types.ts:24`](../packages/compaction/compaction/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `sourceCommandId` | 可选 | `string` | +| `turn` | 必需 | [`OptionalSessionSeq`](#persistence-type-sha256-3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f) | + + + +### `{ decision, durationMs, exitCode?, handlerId, … }` SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` @@ -2812,71 +5745,9 @@ SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` | `stderrSummary` | 可选 | `string` | | `turn` | 必需 | `number` | - + -### `event:image/offload` - -SHA-256: `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:image/offload.data`](#persistence-type-eventimageoffloaddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"image/offload"` | - - - -### `event:image/offload.data` - -SHA-256: `477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028` - -来源:[`packages/compaction/compaction-image-offload/src/projection.ts:25`](../packages/compaction/compaction-image-offload/src/projection.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `targets` | 必需 | [`event:image/offload.data.targets`](#persistence-type-eventimageoffloaddatatargets) | - - - -### `event:image/offload.data.targets` - -SHA-256: `9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb` - -[`packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget`](#persistence-type-packagescompactioncompaction-image-offloadsrcprojectiontsimageoffloadtarget) 的数组。 - - - -### `event:llm/retry` - -SHA-256: `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/llm/llm-retry/src/types.ts#LlmRetryEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretryeventdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"llm/retry"` | - - - -### `event:llm/retry-started` - -SHA-256: `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretrystartedeventdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"llm/retry-started"` | - - - -### `event:llm/retry.data[0]` +### `{ delayMs, failure, maxRetries, mode, … }` SHA-256: `cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced` @@ -2885,7 +5756,7 @@ SHA-256: `cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced` | 属性 | 存在性 | 类型 | |---|---|---| | `delayMs` | 必需 | `number` | -| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `failure` | 必需 | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | | `maxRetries` | 必需 | `number` | | `mode` | 必需 | `"normal"` | | `policyKey` | 必需 | `string` | @@ -2895,9 +5766,9 @@ SHA-256: `cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced` | `step` | 必需 | `number` | | `turn` | 必需 | `number` | - + -### `event:llm/retry.data[1]` +### `{ delayMs, failure, mode, policyKey, … }` SHA-256: `374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b` @@ -2906,7 +5777,7 @@ SHA-256: `374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b` | 属性 | 存在性 | 类型 | |---|---|---| | `delayMs` | 必需 | `number` | -| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `failure` | 必需 | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | | `mode` | 必需 | `"always"` | | `policyKey` | 必需 | `string` | | `provider` | 必需 | `string` | @@ -2915,278 +5786,409 @@ SHA-256: `374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b` | `step` | 必需 | `number` | | `turn` | 必需 | `number` | - + -### `event:model/selection` +### `{ description, name }` -SHA-256: `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` +SHA-256: `83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693` + +来源:[`packages/skill/tool-skill/src/index.ts:40`](../packages/skill/tool-skill/src/index.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/api/session-controller/src/types.ts#ModelSelection`](#persistence-type-packagesapisession-controllersrctypestsmodelselection) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"model/selection"` | +| `description` | 必需 | `string` | +| `name` | 必需 | `string` | - + -### `event:permission/preset` +### `{ description, name }[]` -SHA-256: `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` +SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` + +[`{ description, name }`](#persistence-type-sha256-83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693) 的数组。 + + + +### `{ dialect, handlerId, matcher?, point, … }` + +SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` + +来源:[`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:permission/preset.data`](#persistence-type-eventpermissionpresetdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"permission/preset"` | +| `dialect` | 必需 | [`HookDialect`](#persistence-type-sha256-a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb) | +| `handlerId` | 必需 | `string` | +| `matcher` | 可选 | `string` | +| `point` | 必需 | `string` | +| `turn` | 必需 | `number` | - + -### `event:permission/preset.data` +### `{ end, start }` -SHA-256: `8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad` +SHA-256: `9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2` -来源:[`packages/interaction/permission-presets/src/index.ts:57`](../packages/interaction/permission-presets/src/index.ts) +来源:[`packages/compaction/compaction/src/types.ts:38`](../packages/compaction/compaction/src/types.ts) · [`packages/compaction/compaction/src/types.ts:84`](../packages/compaction/compaction/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `preset` | 必需 | `string` | +| `end` | 必需 | `number` | +| `start` | 必需 | `number` | - + -### `event:plan/mode` +### `{ endSeq, op, startSeq }` -SHA-256: `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` +SHA-256: `bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825` + +来源:[`packages/core/session/src/types.ts:464`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:plan/mode.data`](#persistence-type-eventplanmodedata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"plan/mode"` | +| `endSeq` | 必需 | `number` | +| `op` | 必需 | `"replace"` | +| `startSeq` | 必需 | `number` | - + -### `event:plan/mode.data` +### `{ error, kind: "error" }` -SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5` +SHA-256: `79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985` -来源:[`packages/plan/plan-mode/src/index.ts:47`](../packages/plan/plan-mode/src/index.ts) +来源:[`packages/core/session/src/types.ts:212`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `active` | 必需 | `boolean` | +| `error` | 必需 | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | +| `kind` | 必需 | `"error"` | - + -### `event:request/context` +### `{ error?, message, meta?, step, … }` -SHA-256: `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` +SHA-256: `5302e763151277614b97e77f00e3b326694c6c1247b916a20503c344dc970777` + +来源:[`packages/core/session/src/types.ts:375`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/core/session/src/types.ts#RequestContext`](#persistence-type-packagescoresessionsrctypestsrequestcontext) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"request/context"` | +| `error` | 可选 | [`{ code, name, reason? }`](#persistence-type-sha256-a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735) | +| `message` | 必需 | [`ToolResultMessage`](#persistence-type-sha256-4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731) | +| `meta` | 可选 | [`JsonValue`](#persistence-type-sha256-c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6) | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | - + -### `event:request/header` +### `{ failure, kind: "aborted" }` -SHA-256: `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` +SHA-256: `8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0` + +来源:[`packages/llm/llm/src/types.ts:161`](../packages/llm/llm/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:request/header.data`](#persistence-type-eventrequestheaderdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"request/header"` | +| `failure` | 必需 | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | +| `kind` | 必需 | `"aborted"` | - + -### `event:request/header.data` +### `{ failure, kind: "error" }` -SHA-256: `2f0aefb72ab453c4bf21a6687f436775d359dc6f8f10410fd4c0615b20bd9d76` +SHA-256: `693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057` -来源:[`packages/core/session/src/types.ts:370`](../packages/core/session/src/types.ts) +来源:[`packages/llm/llm/src/types.ts:162`](../packages/llm/llm/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `header` | 必需 | [`packages/core/session/src/types.ts#EpochHeader`](#persistence-type-packagescoresessionsrctypestsepochheader) | -| `reason` | 必需 | [`packages/core/session/src/types.ts#RequestHeaderReason`](#persistence-type-packagescoresessionsrctypestsrequestheaderreason) | +| `failure` | 必需 | [`LlmFailure`](#persistence-type-sha256-5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca) | +| `kind` | 必需 | `"error"` | + + + +### `{ header, reason, startsSeries? }` + +SHA-256: `ad0c38a0adb82a94c925456df41586d9b5f9202fca18593eae2213d4445b4585` + +来源:[`packages/core/session/src/types.ts:390`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `header` | 必需 | [`EpochHeader`](#persistence-type-sha256-9a930283b91d493d6347146f2475bb107294b379415ca02162354f46a64164f7) | +| `reason` | 必需 | [`RequestHeaderReason`](#persistence-type-sha256-530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6) | | `startsSeries` | 可选 | `true` | - + -### `event:request/header.data.header.tools` +### `{ headerSeq?, message, step, turn }` -SHA-256: `6d63f25a28b70801937a46b1058be5f52d4efbaf3516141470463ae469b59c23` +SHA-256: `51c78ccc9023ce6642d07fb9a10cbf942ff7e313d5b304ddc77218df71da708f` -[`packages/llm/llm/src/types.ts#ToolSchema`](#persistence-type-packagesllmllmsrctypeststoolschema) 的数组。 - - - -### `event:request/header.data.header.tools[0].parameters` - -SHA-256: `0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f` +来源:[`packages/core/session/src/types.ts:311`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| [`string`] | 索引签名 | `unknown`(不透明) | +| `headerSeq` | 可选 | `number` | +| `message` | 必需 | [`DeveloperMessage`](#persistence-type-sha256-f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b) | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | - + -### `event:sandbox/mode` +### `{ height, width }` -SHA-256: `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` +SHA-256: `0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef` + +来源:[`packages/attachment/attachment/src/types.ts:28`](../packages/attachment/attachment/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `height` | 必需 | `number` | +| `width` | 必需 | `number` | + + + +### `{ id, outcome }` + +SHA-256: `93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9` + +来源:[`packages/interaction/user-approval/src/types.ts:55`](../packages/interaction/user-approval/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `outcome` | 必需 | [`ApprovalOutcome`](#persistence-type-sha256-930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7) | + + + +### `{ ignorable?, seq, sourceEventSeqs?, surfaceOp, … }` + +SHA-256: `998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `string` | + + + +### `{ ignorable?, seq, surfaceOp, time, … }` + +SHA-256: `7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `string` | + + + +### `{ ignorable?, seq, time, type }` + +SHA-256: `e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:sandbox/mode.data`](#persistence-type-eventsandboxmodedata) | | `ignorable` | 可选 | `true` | | `seq` | 必需 | `number` | | `time` | 必需 | `number` | -| `type` | 必需 | `"sandbox/mode"` | +| `type` | 必需 | `string` | - + -### `event:sandbox/mode.data` - -SHA-256: `9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e` - -来源:[`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/sandbox/sandbox-policy/src/session-mode.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `mode` | 必需 | [`packages/sandbox/sandbox/src/index.ts#SandboxMode`](#persistence-type-packagessandboxsandboxsrcindextssandboxmode) | -| `source` | 可选 | `"delegation"` | - - - -### `event:schedule/change` - -SHA-256: `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/schedule/schedule/src/types.ts#ScheduleChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulechange) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"schedule/change"` | - - - -### `event:session-log-deepseek/delivery-accepted` - -SHA-256: `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:session-log-deepseek/delivery-accepted.data`](#persistence-type-eventsession-log-deepseekdelivery-accepteddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"session-log-deepseek/delivery-accepted"` | - - - -### `event:session-log-deepseek/delivery-accepted.data` - -SHA-256: `8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52` - -来源:[`packages/session/session-log-deepseek/src/types.ts:81`](../packages/session/session-log-deepseek/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `sessionFormatVersion` | 可选 | `number` | -| `sessionId` | 必需 | `string` | -| `throughSeq` | 必需 | `number` | - - - -### `event:session/end-seed` - -SHA-256: `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:session/end-seed.data`](#persistence-type-eventsessionend-seeddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"session/end-seed"` | - - - -### `event:session/end-seed.data` +### `{ inherited? }` SHA-256: `17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3` -来源:[`packages/core/session/src/types.ts:405`](../packages/core/session/src/types.ts) +来源:[`packages/core/session/src/types.ts:427`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| | `inherited` | 可选 | `true` | - + -### `event:session/title` +### `{ inserted, outcome?, removedCount?, start, … }` -SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` +SHA-256: `dc4bd7ac827f4b1f9236f9a157a4b4cc171a0588064a611e43edd95f62c68130` + +来源:[`packages/core/agent/src/types.ts:87`](../packages/core/agent/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/session/session-title/src/types.ts#SessionTitleEventData`](#persistence-type-packagessessionsession-titlesrctypestssessiontitleeventdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"session/title"` | +| `inserted` | 必需 | [`UserMessage[]`](#persistence-type-sha256-d1f27cf1650e5f59d5d6e95ce6dfd92b31757af076a8ab6418a70b6dbdd53621) | +| `outcome` | 可选 | `"canceled"` | +| `removedCount` | 可选 | `number` | +| `start` | 必需 | `number` | +| `target` | 必需 | [`InboxTarget`](#persistence-type-sha256-96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c) | - + -### `event:session/title-llm-request` +### `{ interrupted?, message, step, stream, … }` -SHA-256: `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` +SHA-256: `1ccb56061942f5ccb0d30c9e4f2883b9d115ff906560029de637b61d3cde896d` + +来源:[`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData`](#persistence-type-packagessessionsession-title-llmsrcindextssessiontitlellmrequesteventdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"session/title-llm-request"` | +| `interrupted` | 可选 | `true` | +| `message` | 必需 | [`AssistantMessage`](#persistence-type-sha256-fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be) | +| `step` | 必需 | `number` | +| `stream` | 必需 | [`AssistantStreamRecord[]`](#persistence-type-sha256-84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7) | +| `turn` | 必需 | `number` | +| `usage` | 可选 | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | - + -### `event:session/title-llm-request.data.messages` +### `{ kind: "aborted", reason }` -SHA-256: `478738df7e7d2b103b09fb937817a9302c81076809f2b341169e00a9419c5665` +SHA-256: `0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3` -[`packages/llm/llm/src/message.ts#Message`](#persistence-type-packagesllmllmsrcmessagetsmessage) 的数组。 +来源:[`packages/core/session/src/types.ts:204`](../packages/core/session/src/types.ts) - +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"aborted"` | +| `reason` | 必需 | [`TurnEndCancelCause`](#persistence-type-sha256-1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0) | -### `event:session/title-llm-request.data.messages[0].role` + -SHA-256: `acd36e1717d2b4ef9e98a8e6fac17ca1203f3f448e5bca51677f129a8f4999e2` +### `{ kind: "blocked" }` -以下类型之一: +SHA-256: `023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4` -- `"assistant"` -- `"system"` -- `"user"` +来源:[`packages/core/session/src/types.ts:206`](../packages/core/session/src/types.ts) - +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"blocked"` | -### `event:session/title.data.source[0]` + + +### `{ kind: "completed" }` + +SHA-256: `b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0` + +来源:[`packages/core/session/src/types.ts:202`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"completed"` | + + + +### `{ kind: "cordis-host-runner" }` + +SHA-256: `02b2c23f2d94b028c9588a8faace3fce1217405db346da3389368b495457bf79` + +来源:[`packages/extensions/cordis-host-runner/src/index.ts:14`](../packages/extensions/cordis-host-runner/src/index.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"cordis-host-runner"` | + + + +### `{ kind: "disposed" }` + +SHA-256: `4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db` + +来源:[`packages/core/session/src/types.ts:193`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"disposed"` | + + + +### `{ kind: "dsh-session-title-llm" }` + +SHA-256: `290f32bfd81ff85a8095886a8066fae06e885942b63a8bcd6a8d66d328445808` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "catalog" }` + +SHA-256: `80677c8c8b804189a0fde8aa70dd4ad7af8bb12dfd03027e8e023c8592c838bc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "instructions" }` + +SHA-256: `224aa11d4d5f88c450822d01b99e6ca5e3a9c7f26a5ede10bae33384a09ef4dc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "notice" }` + +SHA-256: `8338ee303e2bd448e9e6144069942f63e3cfd5868962bddc9347d7009e8919d6` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"dsh-session-title-llm"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "dsh-session-title-llm", form: "recall" }` + +SHA-256: `b2a5c8c008a31e3dc6c3013502f2356aca13894b31c8e70601fa92f2d40d1dba` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "relay" }` + +SHA-256: `7eaef7a763ba5b949b8464bc8add8980a3a5ab566014b69787aeba71e5dfe07b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"dsh-session-title-llm"` | + + + +### `{ kind: "dsh-session-title-llm", form: "snapshot" }` + +SHA-256: `ba4c40b4381e0dcdfab8fc9fc75b5c9b3e8f09ef56deeb1bec8e703b0ef8cd6d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"dsh-session-title-llm"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "fallback" }` SHA-256: `1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597` @@ -3196,9 +6198,394 @@ SHA-256: `1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597` |---|---|---| | `kind` | 必需 | `"fallback"` | - + -### `event:session/title.data.source[1]` +### `{ kind: "forked" }` + +SHA-256: `ec8b5ff7c77ca6893ac7ba5a0c5b2aefeb52f12c64450b7359660c2a7e8a53d7` + +来源:[`packages/core/session/src/types.ts:228`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"forked"` | + + + +### `{ kind: "hook" }` + +SHA-256: `6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d` + +来源:[`packages/core/session/src/types.ts:192`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"hook"` | +| `reason` | 必需 | `string` | + + + +### `{ kind: "hooks-claude-code" }` + +SHA-256: `0ed8d1108fe7a5e1c3078ef1faea12199a56b6b1216ccaceb0f6103b0c9a7691` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "catalog" }` + +SHA-256: `297fbd8067d7815adae02b89790ec6ff5fb7c2cb0d0eb026e1746c24ec857761` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "instructions" }` + +SHA-256: `b70f3e81fe11b7a5f2504fb47a4502fb8d9c8f0731fdfe8ddcaf9b41f5a6e196` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "notice" }` + +SHA-256: `edbbfff1128099fda7b792c56330d2cb04debc9790988e66d1c3f4026e813e0e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"hooks-claude-code"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "hooks-claude-code", form: "recall" }` + +SHA-256: `87b1a33564b9a4d63b00988a524c12259243953aebb9c9a05127d87b27464df9` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "relay" }` + +SHA-256: `6ea608bdc8a7a63d3d23b84c49721325094db88d136482e43a820945295eee3e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"hooks-claude-code"` | + + + +### `{ kind: "hooks-claude-code", form: "snapshot" }` + +SHA-256: `3bdb8dc6989655b0d4ec361edafb8e2629bc263e1ea591819414fdafc1a413b3` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"hooks-claude-code"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "hooks-codex" }` + +SHA-256: `b4ec0af39fd52ed971990e42f04e5be3204882e555c409eb330f8238eec21569` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "catalog" }` + +SHA-256: `99f0e98184709ad10f27bfdeaafb4457d9d2b413f402331764798cdb7d3cbe4d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "instructions" }` + +SHA-256: `b6f94c17dd9bbd7cd57015198b7c7c88407f0e3b89faab176ca3c11c3d864d3e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "notice" }` + +SHA-256: `854db3efdfb0cd39d30953b28703e519c121f1115cebfffc40369fe86c406dd1` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"hooks-codex"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "hooks-codex", form: "recall" }` + +SHA-256: `3b4f2c9ef2c1217eac596c7b070173cb7896e2fae09e729bc7c56c801e56bb29` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "relay" }` + +SHA-256: `1fdad624334d354820dfb3a26e28d0bc9fc1b62a33f87bab63f715b3f4391bfd` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"hooks-codex"` | + + + +### `{ kind: "hooks-codex", form: "snapshot" }` + +SHA-256: `88841202942c7683b3b7e5ea6a796047ec326b6701ac23e58cc236d85613b9fa` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"hooks-codex"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "interrupted" }` + +SHA-256: `56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23` + +来源:[`packages/core/session/src/types.ts:221`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"interrupted"` | + + + +### `{ kind: "legacy" }` + +SHA-256: `eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c` + +来源:[`packages/core/session/src/types.ts:196`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"legacy"` | + + + +### `{ kind: "max-tokens" }` + +SHA-256: `ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7` + +来源:[`packages/core/session/src/types.ts:214`](../packages/core/session/src/types.ts) · [`packages/llm/llm/src/types.ts:160`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"max-tokens"` | + + + +### `{ kind: "model-selection" }` + +SHA-256: `f7283223aacdc39b0adca728c8cbd4c090a20006a6fecec74421c30e943b489c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "catalog" }` + +SHA-256: `99135d8a3937977955eaac5f8f04f930dcd1562f8450a54a51cde9b921dd59a6` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "instructions" }` + +SHA-256: `f6605d6c57933aeaaf10911b5fbd6c61e655baa181af7192d3240f49d255b90d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "notice" }` + +SHA-256: `a3c6f1ea38e9a61d7a9706057ba65aabe02dfe6d9dd90d4736aa62325d874531` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"model-selection"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "model-selection", form: "recall" }` + +SHA-256: `aae343bc3d663c83f2e8b5e1c7eea5d509dc7a5361bc8bd8b5ac3bb8d3b1ed56` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "relay" }` + +SHA-256: `a15a19ef63cf5d1b711db1d249821dab0cedcd3a9ad09137b47352c93841fd20` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"model-selection"` | + + + +### `{ kind: "model-selection", form: "snapshot" }` + +SHA-256: `52c6113cb0e53f345324bf84f01928bea5d5df57ee80bc0dd65407b8bc5a3734` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"model-selection"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "parent" }` + +SHA-256: `6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800` + +来源:[`packages/core/session/src/types.ts:191`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"parent"` | + + + +### `{ kind: "plan-mode" }` + +SHA-256: `f4a66f654996c093aae700ea4c434ff2ee3569fea9c0e5813ccf6afdccabd163` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "catalog" }` + +SHA-256: `3b04790e08b35241ffa0d38f6d7e4f8788aa921341f6c0d7574a329397c59408` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "instructions" }` + +SHA-256: `408927267422a7b2beb6df354ff7c1406d929a5646554f48adf85eb8372f811c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "notice" }` + +SHA-256: `baccc97ec34be6c4c78e95aa88c85c29820269479445e5b13f956cd64c5e286f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"plan-mode"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "plan-mode", form: "recall" }` + +SHA-256: `f6329fb30c7ea8013e8975ca5e78284fb7685cc6bd620e8aa4e9a99bc81d45eb` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "relay" }` + +SHA-256: `deaae5cd30987d4f49398e8f9d994c125907e7f928300745fb1dbf15f145d0e7` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"plan-mode"` | + + + +### `{ kind: "plan-mode", form: "snapshot" }` + +SHA-256: `8c1c4f72755a78ea163523a46565316e36e9b644382eb48e6635c71a6f412dd2` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"plan-mode"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "provider" }` SHA-256: `b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812` @@ -3207,203 +6594,731 @@ SHA-256: `b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812` | 属性 | 存在性 | 类型 | |---|---|---| | `kind` | 必需 | `"provider"` | -| `model` | 可选 | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | +| `model` | 可选 | [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) | | `provider` | 必需 | `string` | - + -### `event:step/end` +### `{ kind: "ptc-mode" }` -SHA-256: `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` +SHA-256: `dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd` + +来源:[`packages/core/tools/src/ptc.ts:14`](../packages/core/tools/src/ptc.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:step/end.data`](#persistence-type-eventstependdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"step/end"` | +| `kind` | 必需 | `"ptc-mode"` | - + -### `event:step/end.data` +### `{ kind: "repeat-tool-reminder" }` -SHA-256: `ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545` - -来源:[`packages/core/session/src/types.ts:287`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts) +SHA-256: `b062078e899958f99ae464514578b8c093924dfe34bd9a835932b420ff2150b1` | 属性 | 存在性 | 类型 | |---|---|---| -| `step` | 必需 | `number` | -| `turn` | 必需 | `number` | +| `kind` | 必需 | `"repeat-tool-reminder"` | - + -### `event:step/start` +### `{ kind: "repeat-tool-reminder", form: "catalog" }` -SHA-256: `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` +SHA-256: `d85590a5675c6e2fd8164e5792a6cceac714605b8ac228adae5ee668facb1490` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:step/end.data`](#persistence-type-eventstependdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"step/start"` | +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"repeat-tool-reminder"` | - + -### `event:subagent/catalog` +### `{ kind: "repeat-tool-reminder", form: "instructions" }` -SHA-256: `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` +SHA-256: `6f44f32be9bcd9a8bf075c3b575b06c8ed63446386e5b0995c7b73762e68ddae` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent`](#persistence-type-packagessubagentsubagentsrccatalogtssubagentcatalogevent) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"subagent/catalog"` | +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"repeat-tool-reminder"` | - + -### `event:subagent/catalog.data[0]` +### `{ kind: "repeat-tool-reminder", form: "notice" }` -SHA-256: `5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694` +SHA-256: `fe1a7acdeed4d0f5ab483396eaa5b3dc97263b7c10eb4da2f0028cb01728bfc9` | 属性 | 存在性 | 类型 | |---|---|---| -| `childCreatedAt` | 必需 | `number` | -| `childId` | 必需 | `string` | -| `label` | 可选 | `string` | -| `mode` | 必需 | `"one-shot"` | -| `version` | 必需 | `0` | +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"repeat-tool-reminder"` | +| `summary` | 必需 | `string` | - + -### `event:subagent/catalog.data[1]` +### `{ kind: "repeat-tool-reminder", form: "recall" }` -SHA-256: `0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd` +SHA-256: `8620189c8e33582708ece48fd2d20dc4d57912486a17bdbb9aea4c44f7018062` | 属性 | 存在性 | 类型 | |---|---|---| -| `childCreatedAt` | 必需 | `number` | -| `childId` | 必需 | `string` | -| `label` | 必需 | `string` | -| `mode` | 必需 | `"continuable"` | -| `version` | 必需 | `0` | +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"repeat-tool-reminder"` | - + -### `event:subagent/descriptor` +### `{ kind: "repeat-tool-reminder", form: "relay" }` -SHA-256: `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` +SHA-256: `4991dfc415c9efebc36fa6969e1798c7d2e42396cc1e6e0ac7d7c89c5c5c4aea` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortssubagentdescriptordata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"subagent/descriptor"` | +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"repeat-tool-reminder"` | - + -### `event:subagent/model-selection-policy` +### `{ kind: "repeat-tool-reminder", form: "snapshot" }` -SHA-256: `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` +SHA-256: `db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:subagent/model-selection-policy.data`](#persistence-type-eventsubagentmodel-selection-policydata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"subagent/model-selection-policy"` | +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"repeat-tool-reminder"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | - + -### `event:subagent/model-selection-policy.data` +### `{ kind: "runtime-context" }` -SHA-256: `0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f` - -来源:[`packages/subagent/tool-subagent/src/model-selection-state.ts:17`](../packages/subagent/tool-subagent/src/model-selection-state.ts) +SHA-256: `0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789` | 属性 | 存在性 | 类型 | |---|---|---| -| `allowedModels` | 必需 | [`event:subagent/model-selection-policy.data.allowedModels`](#persistence-type-eventsubagentmodel-selection-policydataallowedmodels) | +| `kind` | 必需 | `"runtime-context"` | - + -### `event:subagent/model-selection-policy.data.allowedModels` +### `{ kind: "runtime-context", form: "catalog" }` -SHA-256: `ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec` - -[`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) 的数组。 - - - -### `event:system/message` - -SHA-256: `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` +SHA-256: `58015da1c1950a66daf66ae24913d6a1fc6d1d9ac441b155f8847f7f8584ba8e` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:system/message.data`](#persistence-type-eventsystemmessagedata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | 必需 | `number` | -| `type` | 必需 | `"system/message"` | +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"runtime-context"` | - + -### `event:system/message.data` +### `{ kind: "runtime-context", form: "instructions" }` -SHA-256: `2074f40221b76c75fd314246db558965dc3477dfb440bcc952b1eedc9778e366` - -来源:[`packages/core/session/src/types.ts:310`](../packages/core/session/src/types.ts) +SHA-256: `0eeb17e1df89b1ebc2902116fe7145e0d321ef0db26e6bdebc802cb8513a01c1` | 属性 | 存在性 | 类型 | |---|---|---| -| `message` | 必需 | [`packages/llm/llm/src/message.ts#SystemMessage`](#persistence-type-packagesllmllmsrcmessagetssystemmessage) | -| `step` | 必需 | `number` | -| `turn` | 必需 | `number` | +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"runtime-context"` | - + -### `event:system/message.data.message.source` +### `{ kind: "runtime-context", form: "notice" }` -SHA-256: `23cf7e0cf3fec1283b60fa15713506169bc9c079a08e124d1cb9733baca80b40` - -以下类型之一: - -- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) -- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) -- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) -- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) -- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) -- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) -- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) - - - -### `event:team/member` - -SHA-256: `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` +SHA-256: `cda2345a9be9d139df49ccbd16dcba716f3440178bf20ff8b801fda1f5eb77dc` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:team/member.data`](#persistence-type-eventteammemberdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"team/member"` | +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"runtime-context"` | +| `summary` | 必需 | `string` | - + -### `event:team/member.data` +### `{ kind: "runtime-context", form: "recall" }` + +SHA-256: `96bfb916a727cd4445a594df264c523fc039749a31bfed924b8cc7bb308a5bb0` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"runtime-context"` | + + + +### `{ kind: "runtime-context", form: "relay" }` + +SHA-256: `cb1c8959e1726f82f9a3d2ef2bc90bf8c451a98fd56175e956022124c770c818` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"runtime-context"` | + + + +### `{ kind: "runtime-context", form: "snapshot" }` + +SHA-256: `2aad1179f957631477b582e57cd8f538cb82618fc3fb816bde1171154235b065` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"runtime-context"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "schedule" }` + +SHA-256: `f29d63336e8266d80dd7baeab219436db86341304f6be1cd0edb36f5134c4a47` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"schedule"` | + + + +### `{ kind: "schedule", form: "catalog" }` + +SHA-256: `1e709346005826eb81809eeb76a3f713cf13ad6c5cec75146d07020ab9adc938` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"schedule"` | + + + +### `{ kind: "schedule", form: "instructions" }` + +SHA-256: `1938c8c20f1cba7c82dbedcfa4f14c3ee191cd77ed3314ee1fc676d44cadf3be` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"schedule"` | + + + +### `{ kind: "schedule", form: "notice" }` + +SHA-256: `312aee2f0c42aabbae6cc60d92d596d8453c0aeb061c5868d1755a69ef49e69a` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"schedule"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "schedule", form: "recall" }` + +SHA-256: `a16e567c8cd2c55cf1e911aed3c200c4e1f6febb1459ff2a9e7adf159afb68cb` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"schedule"` | + + + +### `{ kind: "schedule", form: "relay" }` + +SHA-256: `5bc66269cfaf614c0ecda8ecb469f23101a7609793fc2b693ac23c4aecdb575e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"schedule"` | + + + +### `{ kind: "schedule", form: "snapshot" }` + +SHA-256: `28936c614bd4e7e2774806edcbb3cbfd3ee643ac1cbf0bbdff43d915505a8fe3` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"schedule"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "stop" }` + +SHA-256: `1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f` + +来源:[`packages/llm/llm/src/types.ts:158`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"stop"` | + + + +### `{ kind: "time-context" }` + +SHA-256: `b79641a9d25e756636dc0c706fdf3c4583ccb7d4920e009e6e86c0759cf4de4c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"time-context"` | + + + +### `{ kind: "time-context", form: "catalog" }` + +SHA-256: `85fe96bf15d5c7559eec3bae4d6cf1a76fda9f5be05a29c2830cff560cab0c0d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"time-context"` | + + + +### `{ kind: "time-context", form: "instructions" }` + +SHA-256: `f6afe41e3926f422fe849debe90819fddd739f0f59e20be9c71018b9554a7f09` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"time-context"` | + + + +### `{ kind: "time-context", form: "notice" }` + +SHA-256: `ee577a0cc18664c9daee50e9455153321155604f8f1817362f8f4a4b6fb9e1ad` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"time-context"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "time-context", form: "recall" }` + +SHA-256: `756b5e23a5cb2c7f486f366a828f7461c88902af21125bd6810881f4ccbff6cc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"time-context"` | + + + +### `{ kind: "time-context", form: "relay" }` + +SHA-256: `5d7a64ed6aac5551ebf998dc25e1e7b48a144769913f89702840180e61dc3995` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"time-context"` | + + + +### `{ kind: "time-context", form: "snapshot" }` + +SHA-256: `f230c0b583e23b25ee0a61dbe4c05e95c1e2ae44b27939501eb9e03696f0c278` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"time-context"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tmux-context" }` + +SHA-256: `8a046b52331959aa3394680d6acbe09b8a5447c6b61375f263445bfcef19b7f1` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "catalog" }` + +SHA-256: `7df62978a2b7de8540e714152297743e0a622209a46a5ac9513fc0fad73ca23b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "instructions" }` + +SHA-256: `9f65c43e340bba31cdc0fc37bd93ccb68d5e9b36f47a68c207e95a8e68620a5d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "notice" }` + +SHA-256: `b3681c026a0b98e98b103f057dfd217fbe904129c090efd668253ec9aea7fece` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"tmux-context"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "tmux-context", form: "recall" }` + +SHA-256: `fcf81d3c58c13593bf2594e342e31734f4ab2d24938dc610875194c6079749c7` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "relay" }` + +SHA-256: `f97f47b0eb87905ed77cc27c5e4ed75ef805cb372c98905253709de1aab9b63c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"tmux-context"` | + + + +### `{ kind: "tmux-context", form: "snapshot" }` + +SHA-256: `49dab019d00e8c26f27ad2ccff7b604d69e323ae4d17e0d2a7b6b8a830b1ade2` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"tmux-context"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tool-calls" }` + +SHA-256: `287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a` + +来源:[`packages/llm/llm/src/types.ts:159`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"tool-calls"` | + + + +### `{ kind: "tool-goal" }` + +SHA-256: `a2066bd52f61218ba15b758def2641cc6a8bd3d4a594a488ee4c65be356d7e39` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "catalog" }` + +SHA-256: `260523b412c19ad8c2bb00093b07f64245ff8ba6b2f76c5b545303772ac9704c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "instructions" }` + +SHA-256: `6085488d223aeffdef51d7ae17655fc26ab22ee13cbed82a50e62e2b6fb5b918` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "notice" }` + +SHA-256: `8c627d7a45fa406cea879a3922105e27ed4c3c7966e264afaf11ea7a330f2dd1` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"tool-goal"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "tool-goal", form: "recall" }` + +SHA-256: `7554565be416b0342053ee6a46256c9dab07c487349b4a5f10bab1edc151c619` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "relay" }` + +SHA-256: `8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"tool-goal"` | + + + +### `{ kind: "tool-goal", form: "snapshot" }` + +SHA-256: `11638dc58a31496fb6706ced3e23e3a2db1f3b2a8845968c810827a72b5fc811` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"tool-goal"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tool-jobs" }` + +SHA-256: `24ce31aa528272e59f21cd26da9eca08968bcc97529756a749bfdab71746d9c8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "catalog" }` + +SHA-256: `dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "instructions" }` + +SHA-256: `53cf1704ae0709c7678bcf070c83c619fc48ca1b5c173b74cfa8702f22a8e492` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "notice" }` + +SHA-256: `5bb69b88517f6214f2af4d1a6d2b771e271ad3ad695cc9c2c272069ae698c9bc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"tool-jobs"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "tool-jobs", form: "recall" }` + +SHA-256: `dd6cc2bb2a8f28248347021ad93565360b196a042360b4cd16b569d3a2a91f2d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "relay" }` + +SHA-256: `ade057f4fdc387aec6426f48704a1f9359cfc6fee13f27735b07f9b215ec16ca` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"tool-jobs"` | + + + +### `{ kind: "tool-jobs", form: "snapshot" }` + +SHA-256: `c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"tool-jobs"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "tool-registry" }` + +SHA-256: `8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543` + +来源:[`packages/core/tools/src/index.ts:34`](../packages/core/tools/src/index.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"tool-registry"` | + + + +### `{ kind: "user" }` + +SHA-256: `6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7` + +来源:[`packages/api/session-controller/src/types.ts:385`](../packages/api/session-controller/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `clientTimeZone` | 可选 | `string` | +| `kind` | 必需 | `"user"` | +| `rpcId` | 必需 | `string` | + + + +### `{ kind: "user-approval" }` + +SHA-256: `6292bcbedaa97feaec5b48a03bb8144b581b93309d9d6c905f26da7a6a7a0a4f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "catalog" }` + +SHA-256: `825ca23416b1ea9d81442afead5cf9229a6fa05842f042135cc3aa9710a6a2d8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "instructions" }` + +SHA-256: `aa2bf9e82b9fdeb94a42af20031fffa30e4e23f01f4ac39757427d4c64c407f0` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "notice" }` + +SHA-256: `6ccb6bc423fb3952458abf9c1b1c3284208b7e660344b612cc55da773d61afe4` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"user-approval"` | +| `summary` | 必需 | `string` | + + + +### `{ kind: "user-approval", form: "recall" }` + +SHA-256: `022623b9ef98ec47ec3c3bae0c51027c70d2601141c5e92e26a0d83d1b4cef06` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "relay" }` + +SHA-256: `5cdbf342b7748d152bc987b68f58e565e5bba4b227e076e2d2120d87662e45cd` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"user-approval"` | + + + +### `{ kind: "user-approval", form: "snapshot" }` + +SHA-256: `5654685d7557ec747e74887237065e626a5bdfa426ca43f7fbb0b6fee9b0916c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"user-approval"` | +| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) | + + + +### `{ kind: "webhook", form: "notice" }` + +SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` + +来源:[`packages/webhook/webhook/src/types.ts:74`](../packages/webhook/webhook/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `deliveryId` | 必需 | `string` | +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"webhook"` | +| `provider` | 必需 | `string` | +| `ruleId` | 必需 | `string` | +| `source` | 必需 | `string` | +| `summary` | 必需 | `string` | + + + +### `{ max_tokens, messages, model, tools }` + +SHA-256: `930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731` + +来源:[`packages/web/web-search-deepseek/src/provider.ts:61`](../packages/web/web-search-deepseek/src/provider.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `max_tokens` | 必需 | `number` | +| `messages` | 必需 | [`tuple (1 positions)`](#persistence-type-sha256-b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f) | +| `model` | 必需 | `string` | +| `tools` | 必需 | [`tuple (1 positions)`](#persistence-type-sha256-4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8) | + + + +### `{ member, teamId, version }` SHA-256: `b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1` @@ -3411,38 +7326,41 @@ SHA-256: `b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1` | 属性 | 存在性 | 类型 | |---|---|---| -| `member` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammembersnapshot) | +| `member` | 必需 | [`TeamMemberSnapshot`](#persistence-type-sha256-6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25) | | `teamId` | 必需 | `string` | | `version` | 必需 | `2` | - + -### `event:team/member.data.member.context` +### `{ message, step, turn }` -SHA-256: `50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48` +SHA-256: `6bc8e51124d0874bc89e1d0ceff381a9c3cd0fc240667d69f841ce4f60f65fe5` -以下类型之一: - -- `"fork"` -- `"fresh"` - - - -### `event:team/message/delivered` - -SHA-256: `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` +来源:[`packages/core/session/src/types.ts:330`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:team/message/delivered.data`](#persistence-type-eventteammessagedelivereddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"team/message/delivered"` | +| `message` | 必需 | [`SystemMessage`](#persistence-type-sha256-09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363) | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | - + -### `event:team/message/delivered.data` +### `{ message, teamId, version }` + +SHA-256: `ea08ec1df0c33108fd03345b9af199cf04dea450aa045d3c683f216311403403` + +来源:[`packages/experimental/agent-team/src/types.ts:225`](../packages/experimental/agent-team/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `message` | 必需 | [`TeamMessageSnapshot`](#persistence-type-sha256-2eafefdc6f79a4922d68a787a09eaf4dd2b2369c3777fba4c05e800b5678ac8e) | +| `teamId` | 必需 | `string` | +| `version` | 必需 | `2` | + + + +### `{ messageId, targetId, teamId, version }` SHA-256: `0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1` @@ -3455,537 +7373,60 @@ SHA-256: `0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1` | `teamId` | 必需 | `string` | | `version` | 必需 | `2` | - + -### `event:team/message/queued` +### `{ mode, source? }` -SHA-256: `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` +SHA-256: `9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e` + +来源:[`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/sandbox/sandbox-policy/src/session-mode.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:team/message/queued.data`](#persistence-type-eventteammessagequeueddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"team/message/queued"` | +| `mode` | 必需 | [`SandboxMode`](#persistence-type-sha256-fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd) | +| `source` | 可选 | `"delegation"` | - + -### `event:team/message/queued.data` +### `{ policy, source? }` -SHA-256: `0c3f4d2248d9bc9700e2d7253fa71aa9935f5c39af6f11de5727f08cccaf8383` +SHA-256: `11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912` -来源:[`packages/experimental/agent-team/src/types.ts:225`](../packages/experimental/agent-team/src/types.ts) +来源:[`packages/interaction/user-approval/src/index.ts:40`](../packages/interaction/user-approval/src/index.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `message` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesnapshot) | -| `teamId` | 必需 | `string` | -| `version` | 必需 | `2` | +| `policy` | 必需 | [`ApprovalPolicy`](#persistence-type-sha256-05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf) | +| `source` | 可选 | `"delegation"` | - + -### `event:team/task` +### `{ preset }` -SHA-256: `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` +SHA-256: `8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad` + +来源:[`packages/interaction/permission-presets/src/index.ts:57`](../packages/interaction/permission-presets/src/index.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:team/task.data`](#persistence-type-eventteamtaskdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"team/task"` | +| `preset` | 必需 | `string` | - + -### `event:team/task.data` +### `{ reason, turn }` -SHA-256: `a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c` +SHA-256: `e481c46af3813e0010558e93f578b2986acd658404cec2d1679e3ac2a6c48654` -来源:[`packages/experimental/agent-team/src/types.ts:223`](../packages/experimental/agent-team/src/types.ts) +来源:[`packages/core/session/src/types.ts:297`](../packages/core/session/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `task` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtasksnapshot) | -| `teamId` | 必需 | `string` | -| `version` | 必需 | `2` | - - - -### `event:todo/write` - -SHA-256: `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:todo/write.data`](#persistence-type-eventtodowritedata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"todo/write"` | - - - -### `event:todo/write.data` - -SHA-256: `79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99` - -来源:[`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `todos` | 必需 | [`event:todo/write.data.todos`](#persistence-type-eventtodowritedatatodos) | - - - -### `event:todo/write.data.todos` - -SHA-256: `4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea` - -[`packages/todo/tool-todo/src/types.ts#TodoItem`](#persistence-type-packagestodotool-todosrctypeststodoitem) 的数组。 - - - -### `event:todo/write.data.todos[0].status` - -SHA-256: `fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4` - -以下类型之一: - -- `"completed"` -- `"in_progress"` -- `"pending"` - - - -### `event:tool-workflow/agent-end` - -SHA-256: `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentenddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool-workflow/agent-end"` | - - - -### `event:tool-workflow/agent-start` - -SHA-256: `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentstartdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool-workflow/agent-start"` | - - - -### `event:tool-workflow/run-end` - -SHA-256: `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunenddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool-workflow/run-end"` | - - - -### `event:tool-workflow/run-start` - -SHA-256: `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunstartdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool-workflow/run-start"` | - - - -### `event:tool/call` - -SHA-256: `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:tool/call.data`](#persistence-type-eventtoolcalldata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool/call"` | - - - -### `event:tool/call.data` - -SHA-256: `e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1` - -来源:[`packages/core/session/src/types.ts:341`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `arguments` | 必需 | `string` | -| `callId` | 必需 | `string` | -| `name` | 必需 | `string` | -| `step` | 必需 | `number` | +| `reason` | 必需 | [`TurnEndReason`](#persistence-type-sha256-f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402) | | `turn` | 必需 | `number` | - + -### `event:tool/ptc-dispatch` - -SHA-256: `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/core/tools/src/types.ts#PtcDispatchEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatcheventdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool/ptc-dispatch"` | - - - -### `event:tool/ptc-dispatch-start` - -SHA-256: `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/core/tools/src/types.ts#PtcDispatchStartEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatchstarteventdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool/ptc-dispatch-start"` | - - - -### `event:tool/ptc-dispatch.data.error` - -SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735` - -来源:[`packages/core/session/src/types.ts:363`](../packages/core/session/src/types.ts) · [`packages/core/tools/src/types.ts:24`](../packages/core/tools/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `code` | 必需 | `string` | -| `name` | 必需 | `string` | -| `reason` | 可选 | `string` | - - - -### `event:tool/result` - -SHA-256: `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:tool/result.data`](#persistence-type-eventtoolresultdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | 必需 | `number` | -| `type` | 必需 | `"tool/result"` | - - - -### `event:tool/result.data` - -SHA-256: `356aad27134a0e31af67c994ff8b9e4b91acfb6c4917b3bc1f7a62bbf82794d5` - -来源:[`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `error` | 可选 | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | -| `message` | 必需 | [`packages/llm/llm/src/message.ts#ToolResultMessage`](#persistence-type-packagesllmllmsrcmessagetstoolresultmessage) | -| `meta` | 可选 | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | -| `step` | 必需 | `number` | -| `turn` | 必需 | `number` | - - - -### `event:tool/result.data.message.content` - -SHA-256: `8d6a011f3ef7096a4a922ef420458419ff6b20e1eaeece5d331db7585d2f08d6` - -| 位置 | 存在性 | 类型 | -|---|---|---| -| 0 | 必需 | [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) | - - - -### `event:tool/result.data.meta` - -SHA-256: `c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6` - -来源:[`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) - -以下类型之一: - -- [`event:tool/result.data.meta[5]`](#persistence-type-eventtoolresultdatameta5) -- [`event:tool/result.data.meta[5][0][6]`](#persistence-type-eventtoolresultdatameta506) -- `string` -- `boolean` -- `null` -- `number` - - - -### `event:tool/result.data.meta[5]` - -SHA-256: `72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227` - -[`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) 的数组。 - - - -### `event:tool/result.data.meta[5][0][6]` - -SHA-256: `529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05` - -来源:[`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| [`string`] | 索引签名 | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | - - - -### `event:turn/end` - -SHA-256: `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:turn/end.data`](#persistence-type-eventturnenddata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"turn/end"` | - - - -### `event:turn/end.data` - -SHA-256: `d3e447062a2847dad847dad5168a9508d92c484363dfc76fd82605aa7bd46285` - -来源:[`packages/core/session/src/types.ts:285`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `reason` | 必需 | [`packages/core/session/src/types.ts#TurnEndReason`](#persistence-type-packagescoresessionsrctypeststurnendreason) | -| `turn` | 必需 | `number` | - - - -### `event:turn/end.data.reason[0]` - -SHA-256: `b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0` - -来源:[`packages/core/session/src/types.ts:201`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"completed"` | - - - -### `event:turn/end.data.reason[1]` - -SHA-256: `0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3` - -来源:[`packages/core/session/src/types.ts:203`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"aborted"` | -| `reason` | 必需 | [`packages/core/session/src/types.ts#TurnEndCancelCause`](#persistence-type-packagescoresessionsrctypeststurnendcancelcause) | - - - -### `event:turn/end.data.reason[1].reason[1]` - -SHA-256: `6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800` - -来源:[`packages/core/session/src/types.ts:190`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"parent"` | - - - -### `event:turn/end.data.reason[1].reason[2]` - -SHA-256: `6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d` - -来源:[`packages/core/session/src/types.ts:191`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"hook"` | -| `reason` | 必需 | `string` | - - - -### `event:turn/end.data.reason[1].reason[3]` - -SHA-256: `4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db` - -来源:[`packages/core/session/src/types.ts:192`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"disposed"` | - - - -### `event:turn/end.data.reason[1].reason[4]` - -SHA-256: `eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c` - -来源:[`packages/core/session/src/types.ts:195`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"legacy"` | - - - -### `event:turn/end.data.reason[2]` - -SHA-256: `023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4` - -来源:[`packages/core/session/src/types.ts:205`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"blocked"` | - - - -### `event:turn/end.data.reason[3]` - -SHA-256: `79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985` - -来源:[`packages/core/session/src/types.ts:211`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `error` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | -| `kind` | 必需 | `"error"` | - - - -### `event:turn/end.data.reason[5]` - -SHA-256: `56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23` - -来源:[`packages/core/session/src/types.ts:220`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"interrupted"` | - - - -### `event:turn/start` - -SHA-256: `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`event:turn/start.data`](#persistence-type-eventturnstartdata) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"turn/start"` | - - - -### `event:turn/start.data` - -SHA-256: `f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d` - -来源:[`packages/core/session/src/types.ts:276`](../packages/core/session/src/types.ts) · [`packages/deliverables/workspace-changes/src/types.ts:106`](../packages/deliverables/workspace-changes/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `turn` | 必需 | `number` | - - - -### `event:user/message` - -SHA-256: `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | 必需 | `number` | -| `type` | 必需 | `"user/message"` | - - - -### `event:web/deepseek-search-llm-request` - -SHA-256: `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `data` | 必需 | [`packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest`](#persistence-type-packageswebweb-search-deepseeksrcprovidertsdeepseeksearchllmrequest) | -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `"web/deepseek-search-llm-request"` | - - - -### `event:web/deepseek-search-llm-request.data.body` - -SHA-256: `930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731` - -来源:[`packages/web/web-search-deepseek/src/provider.ts:61`](../packages/web/web-search-deepseek/src/provider.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `max_tokens` | 必需 | `number` | -| `messages` | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages) | -| `model` | 必需 | `string` | -| `tools` | 必需 | [`event:web/deepseek-search-llm-request.data.body.tools`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools) | - - - -### `event:web/deepseek-search-llm-request.data.body.messages` - -SHA-256: `b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f` - -| 位置 | 存在性 | 类型 | -|---|---|---| -| 0 | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0) | - - - -### `event:web/deepseek-search-llm-request.data.body.messages[0]` +### `{ role: "user" }` SHA-256: `9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5` @@ -3993,45 +7434,1217 @@ SHA-256: `9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5` | 属性 | 存在性 | 类型 | |---|---|---| -| `content` | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages[0].content`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content) | +| `content` | 必需 | [`tuple (1 positions)`](#persistence-type-sha256-8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9) | | `role` | 必需 | `"user"` | - + -### `event:web/deepseek-search-llm-request.data.body.messages[0].content` +### `{ sessionFormatVersion?, sessionId, throughSeq }` -SHA-256: `8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9` +SHA-256: `8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52` -| 位置 | 存在性 | 类型 | -|---|---|---| -| 0 | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) | - - - -### `event:web/deepseek-search-llm-request.data.body.messages[0].content[0]` - -SHA-256: `4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c` - -来源:[`packages/llm/llm/src/types.ts:61`](../packages/llm/llm/src/types.ts) · [`packages/web/web-search-deepseek/src/provider.ts:66`](../packages/web/web-search-deepseek/src/provider.ts) +来源:[`packages/session/session-log-deepseek/src/types.ts:81`](../packages/session/session-log-deepseek/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `text` | 必需 | `string` | -| `type` | 必需 | `"text"` | +| `sessionFormatVersion` | 可选 | `number` | +| `sessionId` | 必需 | `string` | +| `throughSeq` | 必需 | `number` | - + -### `event:web/deepseek-search-llm-request.data.body.tools` +### `{ shadowedRange, shadowedSeqs, shadowedTokenCount }` -SHA-256: `4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8` +SHA-256: `5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438` -| 位置 | 存在性 | 类型 | +来源:[`packages/compaction/compaction/src/types.ts:82`](../packages/compaction/compaction/src/types.ts) + +| 属性 | 存在性 | 类型 | |---|---|---| -| 0 | 必需 | [`event:web/deepseek-search-llm-request.data.body.tools[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools0) | +| `shadowedRange` | 必需 | [`{ end, start }`](#persistence-type-sha256-9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2) | +| `shadowedSeqs` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `shadowedTokenCount` | 必需 | `number` | - + -### `event:web/deepseek-search-llm-request.data.body.tools[0]` +### `{ step, stream, turn }` + +SHA-256: `54f9276a1617d7c12594722c89cfe864bcbe4517e9a6f9c98bab14f199a135e0` + +来源:[`packages/core/session/src/types.ts:355`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `step` | 必需 | `number` | +| `stream` | 必需 | [`AssistantStreamRecord[]`](#persistence-type-sha256-84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7) | +| `turn` | 必需 | `number` | + + + +### `{ step, turn }` + +SHA-256: `ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545` + +来源:[`packages/core/session/src/types.ts:299`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:301`](../packages/core/session/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +### `{ targets }` + +SHA-256: `477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028` + +来源:[`packages/compaction/compaction-image-offload/src/projection.ts:25`](../packages/compaction/compaction-image-offload/src/projection.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `targets` | 必需 | [`ImageOffloadTarget[]`](#persistence-type-sha256-9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb) | + + + +### `{ task, teamId, version }` + +SHA-256: `a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c` + +来源:[`packages/experimental/agent-team/src/types.ts:223`](../packages/experimental/agent-team/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `task` | 必需 | [`TeamTaskSnapshot`](#persistence-type-sha256-51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357) | +| `teamId` | 必需 | `string` | +| `version` | 必需 | `2` | + + + +### `{ todos }` + +SHA-256: `79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99` + +来源:[`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `todos` | 必需 | [`TodoItem[]`](#persistence-type-sha256-4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea) | + + + +### `{ turn }` + +SHA-256: `f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d` + +来源:[`packages/core/session/src/types.ts:288`](../packages/core/session/src/types.ts) · [`packages/deliverables/workspace-changes/src/types.ts:106`](../packages/deliverables/workspace-changes/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `turn` | 必需 | `number` | + + + + + +### `{ type: "agent-preset/selected" }` + +SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ agentPreset }`](#persistence-type-sha256-6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"agent-preset/selected"` | + + + + + +### `{ type: "agent/inbox/spliced" }` + +SHA-256: `1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ inserted, outcome?, removedCount?, start, … }`](#persistence-type-sha256-dc4bd7ac827f4b1f9236f9a157a4b4cc171a0588064a611e43edd95f62c68130) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"agent/inbox/spliced"` | + + + + + +### `{ type: "approval/asked" }` + +SHA-256: `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ callId?, id, reason?, toolName }`](#persistence-type-sha256-45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"approval/asked"` | + + + + + +### `{ type: "approval/decided" }` + +SHA-256: `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ id, outcome }`](#persistence-type-sha256-93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"approval/decided"` | + + + + + +### `{ type: "approval/policy" }` + +SHA-256: `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ policy, source? }`](#persistence-type-sha256-11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"approval/policy"` | + + + + + +### `{ type: "assistant/attempt" }` + +SHA-256: `15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ step, stream, turn }`](#persistence-type-sha256-54f9276a1617d7c12594722c89cfe864bcbe4517e9a6f9c98bab14f199a135e0) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"assistant/attempt"` | + + + + + +### `{ type: "assistant/message" }` + +SHA-256: `1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ interrupted?, message, step, stream, … }`](#persistence-type-sha256-1ccb56061942f5ccb0d30c9e4f2883b9d115ff906560029de637b61d3cde896d) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"assistant/message"` | + + + +### `{ type: "block-end" }` + +SHA-256: `d4b739491689cc6bb13d07ffac1a32239875abda364c0d5edd8f74faf5e9c00d` + +来源:[`packages/llm/llm/src/types.ts:445`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `block` | 必需 | [`ContentBlock`](#persistence-type-sha256-8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5) | +| `index` | 必需 | `number` | +| `type` | 必需 | `"block-end"` | + + + +### `{ type: "block-start" }` + +SHA-256: `3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90` + +来源:[`packages/llm/llm/src/types.ts:441`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blockType` | 必需 | [`ContentBlockType`](#persistence-type-sha256-7d65acf0a3a43a8f445ce5d3320b42eca492739fc931b2a7516bfb8368dc2c68) | +| `index` | 必需 | `number` | +| `type` | 必需 | `"block-start"` | + + + +### `{ type: "chunk" }` + +SHA-256: `487b65c37bfedb8b72088c4107a0a90a6249701f6b26745f6d98f9b8a22b07c7` + +来源:[`packages/llm/llm/src/assistant-stream.ts:44`](../packages/llm/llm/src/assistant-stream.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `chunk` | 必需 | [`StreamChunk`](#persistence-type-sha256-47e9095591ae36e7c39ee62553097772f2bfa16304536a72dbbc3f691f605180) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"chunk"` | + + + + + +### `{ type: "command/done" }` + +SHA-256: `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ commandId, kind, sourceEventSeq?, text? }`](#persistence-type-sha256-5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"command/done"` | + + + + + +### `{ type: "command/run" }` + +SHA-256: `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ args?, commandId, name, source }`](#persistence-type-sha256-a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"command/run"` | + + + + + +### `{ type: "compaction/end" }` + +SHA-256: `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ compactionId, error?, sourceCommandId?, turn }`](#persistence-type-sha256-ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/end"` | + + + + + +### `{ type: "compaction/prune" }` + +SHA-256: `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ shadowedRange, shadowedSeqs, shadowedTokenCount }`](#persistence-type-sha256-5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/prune"` | + + + + + +### `{ type: "compaction/start" }` + +SHA-256: `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ compactionId, sourceCommandId?, turn }`](#persistence-type-sha256-3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/start"` | + + + + + +### `{ type: "compaction/summary" }` + +SHA-256: `e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`union (2 variants)`](#persistence-type-sha256-9947aa5938fe19a895298da412917acbf9ffb5093a73ab8baa257e6ae9e63a07) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/summary"` | + + + + + +### `{ type: "deliverables/presented" }` + +SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ callId, files, turn }`](#persistence-type-sha256-1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"deliverables/presented"` | + + + + + +### `{ type: "developer/message" }` + +SHA-256: `eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ headerSeq?, message, step, turn }`](#persistence-type-sha256-51c78ccc9023ce6642d07fb9a10cbf942ff7e313d5b304ddc77218df71da708f) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"developer/message"` | + + + + + +### `{ type: "feedback/message-delete" }` + +SHA-256: `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`MessageFeedbackDelete`](#persistence-type-sha256-7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"feedback/message-delete"` | + + + + + +### `{ type: "feedback/message-put" }` + +SHA-256: `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`MessageFeedbackPut`](#persistence-type-sha256-aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"feedback/message-put"` | + + + + + +### `{ type: "feedback/record" }` + +SHA-256: `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`FeedbackRecord`](#persistence-type-sha256-7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"feedback/record"` | + + + +### `{ type: "finish" }` + +SHA-256: `a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1` + +来源:[`packages/llm/llm/src/types.ts:447`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `reason` | 必需 | [`FinishReason`](#persistence-type-sha256-5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80) | +| `replayState` | 可选 | [`ReplayEnvelope`](#persistence-type-sha256-0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555) | +| `type` | 必需 | `"finish"` | + + + + + +### `{ type: "goal/change" }` + +SHA-256: `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`GoalChangeMeta`](#persistence-type-sha256-7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"goal/change"` | + + + + + +### `{ type: "hook/invoked" }` + +SHA-256: `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ dialect, handlerId, matcher?, point, … }`](#persistence-type-sha256-119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"hook/invoked"` | + + + + + +### `{ type: "hook/result" }` + +SHA-256: `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ decision, durationMs, exitCode?, handlerId, … }`](#persistence-type-sha256-8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"hook/result"` | + + + + + +### `{ type: "image/offload" }` + +SHA-256: `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ targets }`](#persistence-type-sha256-477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"image/offload"` | + + + + + +### `{ type: "llm/retry" }` + +SHA-256: `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`LlmRetryEventData`](#persistence-type-sha256-c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"llm/retry"` | + + + + + +### `{ type: "llm/retry-started" }` + +SHA-256: `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`LlmRetryStartedEventData`](#persistence-type-sha256-6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"llm/retry-started"` | + + + + + +### `{ type: "model/selection" }` + +SHA-256: `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`ModelSelection`](#persistence-type-sha256-f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"model/selection"` | + + + + + +### `{ type: "permission/preset" }` + +SHA-256: `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ preset }`](#persistence-type-sha256-8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"permission/preset"` | + + + + + +### `{ type: "plan/mode" }` + +SHA-256: `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ active }`](#persistence-type-sha256-20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"plan/mode"` | + + + +### `{ type: "reasoning-chunks" }` + +SHA-256: `71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd` + +来源:[`packages/llm/llm/src/assistant-stream.ts:28`](../packages/llm/llm/src/assistant-stream.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `dt` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `index` | 必需 | `number` | +| `texts` | 必需 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `time0` | 必需 | `number` | +| `type` | 必需 | `"reasoning-chunks"` | + + + +### `{ type: "reasoning-delta" }` + +SHA-256: `2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095` + +来源:[`packages/llm/llm/src/types.ts:443`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `index` | 必需 | `number` | +| `text` | 必需 | `string` | +| `type` | 必需 | `"reasoning-delta"` | + + + + + +### `{ type: "request/context" }` + +SHA-256: `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`RequestContext`](#persistence-type-sha256-b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"request/context"` | + + + + + +### `{ type: "request/header" }` + +SHA-256: `4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ header, reason, startsSeries? }`](#persistence-type-sha256-ad0c38a0adb82a94c925456df41586d9b5f9202fca18593eae2213d4445b4585) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"request/header"` | + + + + + +### `{ type: "sandbox/mode" }` + +SHA-256: `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ mode, source? }`](#persistence-type-sha256-9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"sandbox/mode"` | + + + + + +### `{ type: "schedule/change" }` + +SHA-256: `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`ScheduleChange`](#persistence-type-sha256-e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"schedule/change"` | + + + + + +### `{ type: "session-log-deepseek/delivery-accepted" }` + +SHA-256: `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ sessionFormatVersion?, sessionId, throughSeq }`](#persistence-type-sha256-8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session-log-deepseek/delivery-accepted"` | + + + + + +### `{ type: "session/end-seed" }` + +SHA-256: `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ inherited? }`](#persistence-type-sha256-17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session/end-seed"` | + + + + + +### `{ type: "session/title" }` + +SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`SessionTitleEventData`](#persistence-type-sha256-b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session/title"` | + + + + + +### `{ type: "session/title-llm-request" }` + +SHA-256: `fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`SessionTitleLlmRequestEventData`](#persistence-type-sha256-9bc85364d1f37d9c837db6a3bdd3d1d007d923cdc7401a3322be9f12fdc225fd) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session/title-llm-request"` | + + + + + +### `{ type: "step/end" }` + +SHA-256: `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ step, turn }`](#persistence-type-sha256-ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"step/end"` | + + + + + +### `{ type: "step/start" }` + +SHA-256: `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ step, turn }`](#persistence-type-sha256-ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"step/start"` | + + + + + +### `{ type: "subagent/catalog" }` + +SHA-256: `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`SubagentCatalogEvent`](#persistence-type-sha256-3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"subagent/catalog"` | + + + + + +### `{ type: "subagent/descriptor" }` + +SHA-256: `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`SubagentDescriptorData`](#persistence-type-sha256-86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"subagent/descriptor"` | + + + + + +### `{ type: "subagent/model-selection-policy" }` + +SHA-256: `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ allowedModels }`](#persistence-type-sha256-0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"subagent/model-selection-policy"` | + + + + + +### `{ type: "system/message" }` + +SHA-256: `69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ message, step, turn }`](#persistence-type-sha256-6bc8e51124d0874bc89e1d0ceff381a9c3cd0fc240667d69f841ce4f60f65fe5) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"system/message"` | + + + + + +### `{ type: "team/member" }` + +SHA-256: `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ member, teamId, version }`](#persistence-type-sha256-b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/member"` | + + + + + +### `{ type: "team/message/delivered" }` + +SHA-256: `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ messageId, targetId, teamId, version }`](#persistence-type-sha256-0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/message/delivered"` | + + + + + +### `{ type: "team/message/queued" }` + +SHA-256: `21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ message, teamId, version }`](#persistence-type-sha256-ea08ec1df0c33108fd03345b9af199cf04dea450aa045d3c683f216311403403) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/message/queued"` | + + + + + +### `{ type: "team/task" }` + +SHA-256: `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ task, teamId, version }`](#persistence-type-sha256-a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/task"` | + + + +### `{ type: "text-chunks" }` + +SHA-256: `e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33` + +来源:[`packages/llm/llm/src/assistant-stream.ts:21`](../packages/llm/llm/src/assistant-stream.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `dt` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `index` | 必需 | `number` | +| `texts` | 必需 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `time0` | 必需 | `number` | +| `type` | 必需 | `"text-chunks"` | + + + +### `{ type: "text-delta" }` + +SHA-256: `95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65` + +来源:[`packages/llm/llm/src/types.ts:442`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `index` | 必需 | `number` | +| `text` | 必需 | `string` | +| `type` | 必需 | `"text-delta"` | + + + + + +### `{ type: "todo/write" }` + +SHA-256: `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ todos }`](#persistence-type-sha256-79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"todo/write"` | + + + +### `{ type: "tool-call-chunks" }` + +SHA-256: `3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6` + +来源:[`packages/llm/llm/src/assistant-stream.ts:35`](../packages/llm/llm/src/assistant-stream.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `args` | 必需 | [`string[]`](#persistence-type-sha256-93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2) | +| `dt` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `id` | 必需 | `string` | +| `index` | 必需 | `number` | +| `name` | 可选 | `string` | +| `time0` | 必需 | `number` | +| `type` | 必需 | `"tool-call-chunks"` | + + + +### `{ type: "tool-call-delta" }` + +SHA-256: `88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a` + +来源:[`packages/llm/llm/src/types.ts:444`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `argumentsDelta` | 必需 | `string` | +| `id` | 必需 | `string` | +| `index` | 必需 | `number` | +| `name` | 可选 | `string` | +| `type` | 必需 | `"tool-call-delta"` | + + + + + +### `{ type: "tool-workflow/agent-end" }` + +SHA-256: `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`ToolWorkflowAgentEndData`](#persistence-type-sha256-c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/agent-end"` | + + + + + +### `{ type: "tool-workflow/agent-start" }` + +SHA-256: `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`ToolWorkflowAgentStartData`](#persistence-type-sha256-9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/agent-start"` | + + + + + +### `{ type: "tool-workflow/run-end" }` + +SHA-256: `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`ToolWorkflowRunEndData`](#persistence-type-sha256-7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/run-end"` | + + + + + +### `{ type: "tool-workflow/run-start" }` + +SHA-256: `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`ToolWorkflowRunStartData`](#persistence-type-sha256-a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/run-start"` | + + + + + +### `{ type: "tool/call" }` + +SHA-256: `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ arguments, callId, name, step, … }`](#persistence-type-sha256-e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/call"` | + + + + + +### `{ type: "tool/ptc-dispatch" }` + +SHA-256: `100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`PtcDispatchEventData`](#persistence-type-sha256-0ee52de154f8955c7abc82cffebc57452dcc8c44dccbdb6ad16c71a11305ead8) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/ptc-dispatch"` | + + + + + +### `{ type: "tool/ptc-dispatch-start" }` + +SHA-256: `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`PtcDispatchStartEventData`](#persistence-type-sha256-2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/ptc-dispatch-start"` | + + + + + +### `{ type: "tool/result" }` + +SHA-256: `7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ error?, message, meta?, step, … }`](#persistence-type-sha256-5302e763151277614b97e77f00e3b326694c6c1247b916a20503c344dc970777) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/result"` | + + + + + +### `{ type: "turn/end" }` + +SHA-256: `0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ reason, turn }`](#persistence-type-sha256-e481c46af3813e0010558e93f578b2986acd658404cec2d1679e3ac2a6c48654) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"turn/end"` | + + + + + +### `{ type: "turn/start" }` + +SHA-256: `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`{ turn }`](#persistence-type-sha256-f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"turn/start"` | + + + +### `{ type: "usage" }` + +SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515` + +来源:[`packages/llm/llm/src/types.ts:446`](../packages/llm/llm/src/types.ts) + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `type` | 必需 | `"usage"` | +| `usage` | 必需 | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) | + + + + + +### `{ type: "user/message" }` + +SHA-256: `3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`UserMessage`](#persistence-type-sha256-64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) | +| `surfaceOp` | 必需 | [`SurfaceOp`](#persistence-type-sha256-335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"user/message"` | + + + + + +### `{ type: "web/deepseek-search-llm-request" }` + +SHA-256: `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`DeepSeekSearchLlmRequest`](#persistence-type-sha256-2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"web/deepseek-search-llm-request"` | + + + +### `{ type: "web_search_20250305" }` SHA-256: `2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3` @@ -4043,2670 +8656,40 @@ SHA-256: `2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3` | `name` | 必需 | `"web_search"` | | `type` | 必需 | `"web_search_20250305"` | + + -### `event:workspace/changes` +### `{ type: "workspace/changes" }` SHA-256: `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | 属性 | 存在性 | 类型 | |---|---|---| -| `data` | 必需 | [`event:turn/start.data`](#persistence-type-eventturnstartdata) | +| `data` | 必需 | [`{ turn }`](#persistence-type-sha256-f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d) | | `ignorable` | 可选 | `true` | | `seq` | 必需 | `number` | | `time` | 必需 | `number` | | `type` | 必需 | `"workspace/changes"` | - + -### `"every"` +### `{}` -SHA-256: `e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87` - -`"every"` - - - -### `"failed"` - -SHA-256: `b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420` - -`"failed"` - - - -### `"fallback"` - -SHA-256: `d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c` - -`"fallback"` - - - -### `false` - -SHA-256: `0c4205180f75b9ee1e0d878bd9a9851628b5dc18448486389d9c5fdc3f1ccda3` - -`false` - - - -### `"feedback/message-delete"` - -SHA-256: `44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e` - -`"feedback/message-delete"` - - - -### `"feedback/message-put"` - -SHA-256: `6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8` - -`"feedback/message-put"` - - - -### `"feedback/record"` - -SHA-256: `c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954` - -`"feedback/record"` - - - -### `"file"` - -SHA-256: `277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9` - -`"file"` - - - -### `"finish"` - -SHA-256: `bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd` - -`"finish"` - - - -### `"fork"` - -SHA-256: `2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863` - -`"fork"` - - - -### `"fresh"` - -SHA-256: `dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d` - -`"fresh"` - - - -### `"goal"` - -SHA-256: `b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602` - -`"goal"` - - - -### `"goal/change"` - -SHA-256: `237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163` - -`"goal/change"` - - - -### `"hook"` - -SHA-256: `dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc` - -`"hook"` - - - -### `"hook/invoked"` - -SHA-256: `b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611` - -`"hook/invoked"` - - - -### `"hook/result"` - -SHA-256: `a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2` - -`"hook/result"` - - - -### `"image"` - -SHA-256: `fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0` - -`"image"` - - - -### `"image/gif"` - -SHA-256: `de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048` - -`"image/gif"` - - - -### `"image/jpeg"` - -SHA-256: `3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004` - -`"image/jpeg"` - - - -### `"image/offload"` - -SHA-256: `9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49` - -`"image/offload"` - - - -### `"image/png"` - -SHA-256: `58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0` - -`"image/png"` - - - -### `"image/webp"` - -SHA-256: `ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8` - -`"image/webp"` - - - -### `"in-history"` - -SHA-256: `f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5` - -来源:[`packages/llm/llm/src/types.ts:383`](../packages/llm/llm/src/types.ts) - -`"in-history"` - - - -### `"in_progress"` - -SHA-256: `94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378` - -`"in_progress"` - - - -### `"initial"` - -SHA-256: `e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c` - -`"initial"` - - - -### `"instruction-following"` - -SHA-256: `e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486` - -`"instruction-following"` - - - -### `"instructions"` - -SHA-256: `fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5` - -`"instructions"` - - - -### `"interrupted"` - -SHA-256: `69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199` - -`"interrupted"` - - - -### `"legacy"` - -SHA-256: `ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc` - -`"legacy"` - - - -### `"llm/retry"` - -SHA-256: `611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d` - -`"llm/retry"` - - - -### `"llm/retry-started"` - -SHA-256: `4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964` - -`"llm/retry-started"` - - - -### `"max-tokens"` - -SHA-256: `68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe` - -`"max-tokens"` - - - -### `"model"` - -SHA-256: `2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e` - -`"model"` - - - -### `"model/selection"` - -SHA-256: `1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2` - -`"model/selection"` - - - -### `"negative"` - -SHA-256: `b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5` - -`"negative"` - - - -### `"never"` - -SHA-256: `1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b` - -`"never"` - - - -### `"next-step"` - -SHA-256: `3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693` - -`"next-step"` - - - -### `"next-turn"` - -SHA-256: `62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd` - -`"next-turn"` - - - -### `"normal"` - -SHA-256: `3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79` - -`"normal"` - - - -### `"notice"` - -SHA-256: `e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367` - -`"notice"` - - - -### `null` - -SHA-256: `938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615` - -`null` - - - -### `number` - -SHA-256: `0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7` - -来源:[`packages/core/session/src/types.ts:31`](../packages/core/session/src/types.ts) - -`number` - - - -### `"one-shot"` - -SHA-256: `d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2` - -`"one-shot"` - - - -### `"other"` - -SHA-256: `9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4` - -`"other"` - - - -### `packages/api/session-controller/src/types.ts#ModelSelection` - -SHA-256: `f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b` - -来源:[`packages/api/session-controller/src/types.ts:86`](../packages/api/session-controller/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | -| `reasoningEffort` | 可选 | `string` | - - - -### `packages/attachment/attachment/src/types.ts#FileAttachmentRef` - -SHA-256: `f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6` - -来源:[`packages/attachment/attachment/src/types.ts:39`](../packages/attachment/attachment/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `attachmentId` | 必需 | `string` | -| `bytes` | 必需 | `number` | -| `name` | 必需 | `string` | - - - -### `packages/attachment/attachment/src/types.ts#ImageAttachmentRef` - -SHA-256: `b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35` - -来源:[`packages/attachment/attachment/src/types.ts:11`](../packages/attachment/attachment/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `attachmentId` | 必需 | `string` | -| `bytes` | 必需 | `number` | -| `height` | 必需 | `number` | -| `mediaType` | 必需 | [`packages/attachment/attachment/src/types.ts#ImageMediaType`](#persistence-type-packagesattachmentattachmentsrctypestsimagemediatype) | -| `name` | 可选 | `string` | -| `originalDimensions` | 可选 | [`event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions`](#persistence-type-eventagentinboxspliceddatainserted0content02attachmentoriginaldimensions) | -| `width` | 必需 | `number` | - - - -### `packages/attachment/attachment/src/types.ts#ImageMediaType` - -SHA-256: `2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716` - -来源:[`packages/attachment/attachment/src/types.ts:8`](../packages/attachment/attachment/src/types.ts) - -以下类型之一: - -- `"image/gif"` -- `"image/jpeg"` -- `"image/png"` -- `"image/webp"` - - - -### `packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget` - -SHA-256: `1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f` - -来源:[`packages/compaction/compaction-image-offload/src/projection.ts:9`](../packages/compaction/compaction-image-offload/src/projection.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `imageIndexes` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `seq` | 必需 | `number` | - - - -### `packages/context/agent-instructions/src/render.ts#AgentInstructionChange` - -SHA-256: `83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239` - -来源:[`packages/context/agent-instructions/src/render.ts:47`](../packages/context/agent-instructions/src/render.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `action` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action`](#persistence-type-eventagentinboxspliceddatainserted0source16changes0action) | -| `digest` | 可选 | `string` | -| `path` | 必需 | `string` | -| `scope` | 必需 | `string` | - - - -### `packages/context/agent-instructions/src/state.ts#AgentInstructionSource` - -SHA-256: `6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590` - -来源:[`packages/context/agent-instructions/src/state.ts:37`](../packages/context/agent-instructions/src/state.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `baseline` | 可选 | `true` | -| `baselineIdentity` | 可选 | `string` | -| `changes` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes`](#persistence-type-eventagentinboxspliceddatainserted0source16changes) | -| `form` | 必需 | `"instructions"` | -| `kind` | 必需 | `"agent-instructions"` | - - - -### `packages/context/session-reference/src/types.ts#SessionReferenceSource` - -SHA-256: `f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f` - -来源:[`packages/context/session-reference/src/types.ts:13`](../packages/context/session-reference/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"recall"` | -| `kind` | 必需 | `"session-reference"` | -| `references` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[15].references`](#persistence-type-eventagentinboxspliceddatainserted0source15references) | -| `version` | 必需 | `1` | - - - -### `packages/core/agent/src/types.ts#InboxTarget` - -SHA-256: `96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c` - -来源:[`packages/core/agent/src/types.ts:30`](../packages/core/agent/src/types.ts) - -以下类型之一: - -- `"next-step"` -- `"next-turn"` - - - -### `packages/core/session/src/types.ts#EpochHeader` - -SHA-256: `c55a891c7aac496de6ee64c91c1fb65728c977314013033e42c863428aada854` - -来源:[`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `adapterDefaults` | 可选 | [`packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfigadapterdefaults) | -| `config` | 必需 | [`packages/llm/llm/src/call-config.ts#LlmCallConfig`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfig) | -| `tools` | 可选 | [`event:request/header.data.header.tools`](#persistence-type-eventrequestheaderdataheadertools) | - - - -### `packages/core/session/src/types.ts#RequestContext` - -SHA-256: `b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081` - -来源:[`packages/core/session/src/types.ts:242`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `contextWindow` | 可选 | `number` | -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | -| `systemPromptUpdate` | 可选 | `"in-history"` | - - - -### `packages/core/session/src/types.ts#RequestHeaderReason` - -SHA-256: `530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6` - -来源:[`packages/core/session/src/types.ts:261`](../packages/core/session/src/types.ts) - -以下类型之一: - -- `"change"` -- `"initial"` -- `"resume"` -- `"series"` - - - -### `packages/core/session/src/types.ts#SessionHeader` - -SHA-256: `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` - -来源:[`packages/core/session/src/types.ts:93`](../packages/core/session/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `agentPreset` | 可选 | `string` | -| `createdAt` | 必需 | `number` | -| `cwd` | 可选 | `string` | -| `delegationDepth` | 可选 | `number` | -| `id` | 必需 | `string` | -| `isSeeded` | 必需 | `boolean` | -| `origin` | 可选 | `"subagent"` | -| `parentSession` | 可选 | `string` | -| `version` | 必需 | `3` | - - - -### `packages/core/session/src/types.ts#SurfaceOp` - -SHA-256: `335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5` - -来源:[`packages/core/session/src/types.ts:439`](../packages/core/session/src/types.ts) - -以下类型之一: - -- `"append"` -- [`SessionEventEnvelope[6].surfaceOp[1]`](#persistence-type-sessioneventenvelope6surfaceop1) - - - -### `packages/core/session/src/types.ts#TurnEndCancelCause` - -SHA-256: `1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0` - -来源:[`packages/core/session/src/types.ts:195`](../packages/core/session/src/types.ts) - -以下类型之一: - -- [`event:turn/end.data.reason[1].reason[2]`](#persistence-type-eventturnenddatareason1reason2) -- [`event:turn/end.data.reason[1].reason[3]`](#persistence-type-eventturnenddatareason1reason3) -- [`event:turn/end.data.reason[1].reason[4]`](#persistence-type-eventturnenddatareason1reason4) -- [`event:turn/end.data.reason[1].reason[1]`](#persistence-type-eventturnenddatareason1reason1) -- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) - - - -### `packages/core/session/src/types.ts#TurnEndReason` - -SHA-256: `a5a8c15f08af1b0f26f40906e0797b6b0920fd01069e660becce35ab7fc48d77` - -来源:[`packages/core/session/src/types.ts:224`](../packages/core/session/src/types.ts) - -以下类型之一: - -- [`event:turn/end.data.reason[5]`](#persistence-type-eventturnenddatareason5) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) -- [`event:turn/end.data.reason[3]`](#persistence-type-eventturnenddatareason3) -- [`event:turn/end.data.reason[1]`](#persistence-type-eventturnenddatareason1) -- [`event:turn/end.data.reason[2]`](#persistence-type-eventturnenddatareason2) -- [`event:turn/end.data.reason[0]`](#persistence-type-eventturnenddatareason0) - - - -### `packages/core/tools/src/index.ts#ToolRestriction` - -SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f` - -来源:[`packages/core/tools/src/index.ts:682`](../packages/core/tools/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `allow` | 可选 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `deny` | 可选 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | - - - -### `packages/core/tools/src/types.ts#PtcDispatchEventData` - -SHA-256: `8d2e5a3c4230e6ea6c0b5151f02241d0db02cd2551f2df1b6b9700cddcc0dca3` - -来源:[`packages/core/tools/src/types.ts:20`](../packages/core/tools/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `arguments` | 必需 | `unknown`(不透明) | -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `error` | 可选 | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | -| `isError` | 必需 | `boolean` | -| `name` | 必需 | `string` | -| `parentCallId` | 必需 | `string` | -| `rootCallId` | 必需 | `string` | -| `subCallId` | 必需 | `string` | - - - -### `packages/core/tools/src/types.ts#PtcDispatchStartEventData` - -SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f` - -来源:[`packages/core/tools/src/types.ts:11`](../packages/core/tools/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `arguments` | 必需 | `unknown`(不透明) | -| `name` | 必需 | `string` | -| `parentCallId` | 必需 | `string` | -| `rootCallId` | 必需 | `string` | -| `subCallId` | 必需 | `string` | - - - -### `packages/deliverables/tool-present/src/types.ts#PresentedFile` - -SHA-256: `b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97` - -来源:[`packages/deliverables/tool-present/src/types.ts:5`](../packages/deliverables/tool-present/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `description` | 可选 | `string` | -| `path` | 必需 | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamMemberPhase` - -SHA-256: `dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd` - -来源:[`packages/experimental/agent-team/src/types.ts:44`](../packages/experimental/agent-team/src/types.ts) - -以下类型之一: - -- `"active"` -- `"failed"` -- `"provisioning"` - - - -### `packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot` - -SHA-256: `6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25` - -来源:[`packages/experimental/agent-team/src/types.ts:47`](../packages/experimental/agent-team/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `context` | 必需 | [`event:team/member.data.member.context`](#persistence-type-eventteammemberdatamembercontext) | -| `description` | 必需 | `string` | -| `error` | 可选 | `string` | -| `id` | 必需 | `string` | -| `name` | 必需 | `string` | -| `phase` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamMemberPhase`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammemberphase) | -| `provider` | 必需 | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot` - -SHA-256: `5b694f394d5e11609887a3ccfa82844935d49806c37e336b30be2186d649ab94` - -来源:[`packages/experimental/agent-team/src/types.ts:106`](../packages/experimental/agent-team/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | 必需 | `string` | -| `senderId` | 必需 | `string` | -| `senderName` | 必需 | `string` | -| `targetId` | 必需 | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamMessageSource` - -SHA-256: `2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0` - -来源:[`packages/experimental/agent-team/src/types.ts:115`](../packages/experimental/agent-team/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"team-message"` | -| `messageId` | 必需 | `string` | -| `senderId` | 必需 | `string` | -| `senderName` | 必需 | `string` | -| `teamId` | 必需 | `string` | - - - -### `packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot` - -SHA-256: `51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357` - -来源:[`packages/experimental/agent-team/src/types.ts:74`](../packages/experimental/agent-team/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `blockedBy` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `description` | 必需 | `string` | -| `id` | 必需 | `string` | -| `ownerId` | 可选 | `string` | -| `revision` | 必需 | `number` | -| `status` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamTaskStatus`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtaskstatus) | -| `subject` | 必需 | `string` | -| `writeScopes` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | - - - -### `packages/experimental/agent-team/src/types.ts#TeamTaskStatus` - -SHA-256: `b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943` - -来源:[`packages/experimental/agent-team/src/types.ts:71`](../packages/experimental/agent-team/src/types.ts) - -以下类型之一: - -- `"completed"` -- `"deleted"` -- `"in_progress"` -- `"pending"` - - - -### `packages/feedback/command-feedback/src/types.ts#FeedbackRecord` - -SHA-256: `7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344` - -来源:[`packages/feedback/command-feedback/src/types.ts:27`](../packages/feedback/command-feedback/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `category` | 可选 | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | -| `text` | 可选 | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete` - -SHA-256: `7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06` - -来源:[`packages/feedback/message-feedback/src/types.ts:46`](../packages/feedback/message-feedback/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `messageId` | 必需 | `string` | -| `sessionId` | 必需 | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem` - -SHA-256: `3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182` - -来源:[`packages/feedback/message-feedback/src/types.ts:20`](../packages/feedback/message-feedback/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `category` | 可选 | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | -| `createdAt` | 必需 | `number` | -| `messageId` | 必需 | `string` | -| `note` | 可选 | `string` | -| `rating` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackrating) | -| `updatedAt` | 必需 | `number` | -| `version` | 必需 | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut` - -SHA-256: `aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626` - -来源:[`packages/feedback/message-feedback/src/types.ts:38`](../packages/feedback/message-feedback/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `item` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackitem) | -| `sessionId` | 必需 | `string` | - - - -### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating` - -SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2` - -来源:[`packages/feedback/message-feedback/src/types.ts:17`](../packages/feedback/message-feedback/src/types.ts) - -以下类型之一: - -- `"negative"` -- `"positive"` - - - -### `packages/goal/goal/src/domain.ts#GoalChangeMeta` - -SHA-256: `7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438` - -来源:[`packages/goal/goal/src/domain.ts:44`](../packages/goal/goal/src/domain.ts) - -以下类型之一: - -- [`packages/goal/goal/src/domain.ts#GoalClearChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalclearchangemeta) -- [`packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalsnapshotchangemeta) - - - -### `packages/goal/goal/src/domain.ts#GoalClearChangeMeta` - -SHA-256: `cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f` - -来源:[`packages/goal/goal/src/domain.ts:35`](../packages/goal/goal/src/domain.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `cleared` | 必需 | [`packages/goal/goal/src/types.ts#GoalRef`](#persistence-type-packagesgoalgoalsrctypestsgoalref) | -| `clearedAt` | 必需 | `number` | -| `kind` | 必需 | `"goal/change"` | -| `operation` | 必需 | `"clear"` | -| `version` | 必需 | `1` | - - - -### `packages/goal/goal/src/domain.ts#GoalMessageSource` - -SHA-256: `7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc` - -来源:[`packages/goal/goal/src/domain.ts:47`](../packages/goal/goal/src/domain.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `goalId` | 必需 | `string` | -| `kind` | 必需 | `"goal"` | -| `revision` | 必需 | `number` | -| `round` | 必需 | `number` | - - - -### `packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta` - -SHA-256: `1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4` - -来源:[`packages/goal/goal/src/domain.ts:24`](../packages/goal/goal/src/domain.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `createdAt` | 必需 | `number` | -| `goal` | 必需 | [`packages/goal/goal/src/types.ts#GoalSnapshot`](#persistence-type-packagesgoalgoalsrctypestsgoalsnapshot) | -| `kind` | 必需 | `"goal/change"` | -| `operation` | 必需 | [`event:goal/change.data[0].operation`](#persistence-type-eventgoalchangedata0operation) | -| `roundsStarted` | 必需 | `number` | -| `updatedAt` | 必需 | `number` | -| `version` | 必需 | `1` | - - - -### `packages/goal/goal/src/types.ts#GoalBlockReason` - -SHA-256: `84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c` - -来源:[`packages/goal/goal/src/types.ts:52`](../packages/goal/goal/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `code` | 必需 | `string` | -| `message` | 必需 | `string` | - - - -### `packages/goal/goal/src/types.ts#GoalPhase` - -SHA-256: `b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172` - -来源:[`packages/goal/goal/src/types.ts:45`](../packages/goal/goal/src/types.ts) - -以下类型之一: - -- `"active"` -- `"blocked"` -- `"complete"` -- `"paused"` - - - -### `packages/goal/goal/src/types.ts#GoalRef` - -SHA-256: `0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f` - -来源:[`packages/goal/goal/src/types.ts:20`](../packages/goal/goal/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `id` | 必需 | `string` | -| `revision` | 必需 | `number` | - - - -### `packages/goal/goal/src/types.ts#GoalSnapshot` - -SHA-256: `6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25` - -来源:[`packages/goal/goal/src/types.ts:60`](../packages/goal/goal/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `blockedReason` | 可选 | [`packages/goal/goal/src/types.ts#GoalBlockReason`](#persistence-type-packagesgoalgoalsrctypestsgoalblockreason) | -| `id` | 必需 | `string` | -| `maxGoalRounds` | 必需 | `number` | -| `objective` | 必需 | `string` | -| `phase` | 必需 | [`packages/goal/goal/src/types.ts#GoalPhase`](#persistence-type-packagesgoalgoalsrctypestsgoalphase) | -| `revision` | 必需 | `number` | - - - -### `packages/hooks/hook-protocol/src/types.ts#HookDialect` - -SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` - -来源:[`packages/hooks/hook-protocol/src/types.ts:48`](../packages/hooks/hook-protocol/src/types.ts) - -以下类型之一: - -- `"claude-code"` -- `"codex"` - - - -### `packages/interaction/user-approval/src/index.ts#ApprovalPolicy` - -SHA-256: `05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf` - -来源:[`packages/interaction/user-approval/src/index.ts:60`](../packages/interaction/user-approval/src/index.ts) - -以下类型之一: - -- `"ask"` -- `"never"` - - - -### `packages/interaction/user-approval/src/types.ts#ApprovalOutcome` - -SHA-256: `930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7` - -来源:[`packages/interaction/user-approval/src/types.ts:32`](../packages/interaction/user-approval/src/types.ts) - -以下类型之一: - -- `"allowed-once"` -- `"cancelled"` -- `"rejected"` -- `"unavailable"` - - - -### `packages/llm/llm-retry/src/types.ts#LlmRetryEventData` - -SHA-256: `c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1` - -来源:[`packages/llm/llm-retry/src/types.ts:16`](../packages/llm/llm-retry/src/types.ts) - -以下类型之一: - -- [`event:llm/retry.data[0]`](#persistence-type-eventllmretrydata0) -- [`event:llm/retry.data[1]`](#persistence-type-eventllmretrydata1) - - - -### `packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData` - -SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20` - -来源:[`packages/llm/llm-retry/src/types.ts:43`](../packages/llm/llm-retry/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `retry` | 必需 | `number` | -| `retryId` | 必需 | `string` | -| `step` | 必需 | `number` | -| `turn` | 必需 | `number` | - - - -### `packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord` - -SHA-256: `86cf1e44038cb8b11659863dd0efafe682e41b9c782265c1d50e0a687debfc60` - -来源:[`packages/llm/llm/src/assistant-stream.ts:20`](../packages/llm/llm/src/assistant-stream.ts) - -以下类型之一: - -- [`event:assistant/attempt.data.stream[0][2]`](#persistence-type-eventassistantattemptdatastream02) -- [`event:assistant/attempt.data.stream[0][3]`](#persistence-type-eventassistantattemptdatastream03) -- [`event:assistant/attempt.data.stream[0][1]`](#persistence-type-eventassistantattemptdatastream01) -- [`event:assistant/attempt.data.stream[0][0]`](#persistence-type-eventassistantattemptdatastream00) - - - -### `packages/llm/llm/src/call-config.ts#LlmCallConfig` - -SHA-256: `67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0` - -来源:[`packages/llm/llm/src/call-config.ts:23`](../packages/llm/llm/src/call-config.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `maxTokens` | 可选 | `number` | -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | -| `reasoningEffort` | 可选 | `string` | -| `stop` | 可选 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | -| `temperature` | 可选 | `number` | - - - -### `packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults` - -SHA-256: `326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693` - -来源:[`packages/llm/llm/src/call-config.ts:36`](../packages/llm/llm/src/call-config.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `maxTokens` | 可选 | `true` | -| `reasoningEffort` | 可选 | `true` | - - - -### `packages/llm/llm/src/message.ts#AssistantMessage` - -SHA-256: `e50b0a3ed8e6c80b672e4f855c91984f03b5c3fdd5d475bf171171f391a86c83` - -来源:[`packages/llm/llm/src/message.ts:148`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | 必需 | `string` | -| `role` | 必需 | `"assistant"` | -| `source` | 必需 | [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) | - - - -### `packages/llm/llm/src/message.ts#ContextSnapshotSection` - -SHA-256: `86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219` - -来源:[`packages/llm/llm/src/message.ts:65`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `name` | 必需 | `string` | -| `text` | 必需 | `string` | - - - -### `packages/llm/llm/src/message.ts#Message` - -SHA-256: `23c7cce57d20589897f4e2bd5898affc6fc611b87cd0cc8b95be1cfdd8b3a7eb` - -来源:[`packages/llm/llm/src/message.ts:131`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | 必需 | `string` | -| `role` | 必需 | [`event:session/title-llm-request.data.messages[0].role`](#persistence-type-eventsessiontitle-llm-requestdatamessages0role) | -| `source` | 必需 | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | - - - -### `packages/llm/llm/src/message.ts#MessageSource` - -SHA-256: `4c965666d5b42116945bc356087cd5e1fd549e6dece560785ed60511059a8283` - -来源:[`packages/llm/llm/src/message.ts:128`](../packages/llm/llm/src/message.ts) - -以下类型之一: - -- [`packages/context/agent-instructions/src/state.ts#AgentInstructionSource`](#persistence-type-packagescontextagent-instructionssrcstatetsagentinstructionsource) -- [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) -- [`event:agent/inbox/spliced.data.inserted[0].source[11]`](#persistence-type-eventagentinboxspliceddatainserted0source11) -- [`event:agent/inbox/spliced.data.inserted[0].source[19]`](#persistence-type-eventagentinboxspliceddatainserted0source19) -- [`packages/skill/tool-skill/src/index.ts#SkillCatalogSource`](#persistence-type-packagesskilltool-skillsrcindextsskillcatalogsource) -- [`packages/skill/skill/src/index.ts#SkillInvocationSource`](#persistence-type-packagesskillskillsrcindextsskillinvocationsource) -- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) -- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) -- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) -- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) -- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) -- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) -- [`packages/context/session-reference/src/types.ts#SessionReferenceSource`](#persistence-type-packagescontextsession-referencesrctypestssessionreferencesource) -- [`packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestssubagentsettledmessagesource) -- [`packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestsagentmessagesource) -- [`packages/goal/goal/src/domain.ts#GoalMessageSource`](#persistence-type-packagesgoalgoalsrcdomaintsgoalmessagesource) -- [`packages/experimental/agent-team/src/types.ts#TeamMessageSource`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesource) -- [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) -- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) -- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) - - - -### `packages/llm/llm/src/message.ts#ModelMessageSource` - -SHA-256: `719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91` - -来源:[`packages/llm/llm/src/message.ts:24`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `kind` | 必需 | `"model"` | -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | -| `replayState` | 可选 | `unknown`(不透明) | - - - -### `packages/llm/llm/src/message.ts#SystemMessage` - -SHA-256: `302b01ddddcbb3b16cfa3fba2a5d99f5082a55fbd9dc5c83a179a228b8a6a0ca` - -来源:[`packages/llm/llm/src/message.ts:158`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | 必需 | `string` | -| `role` | 必需 | `"system"` | -| `source` | 必需 | [`event:system/message.data.message.source`](#persistence-type-eventsystemmessagedatamessagesource) | - - - -### `packages/llm/llm/src/message.ts#ToolMessageSource` - -SHA-256: `d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab` - -来源:[`packages/llm/llm/src/message.ts:29`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `callId` | 必需 | `string` | -| `kind` | 必需 | `"tool"` | - - - -### `packages/llm/llm/src/message.ts#ToolResultMessage` - -SHA-256: `1b573e2d5c094fa87e2a8bf409ddd4ac5ba92a123085e168de44b9ccdbd5244c` - -来源:[`packages/llm/llm/src/message.ts:164`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:tool/result.data.message.content`](#persistence-type-eventtoolresultdatamessagecontent) | -| `id` | 必需 | `string` | -| `role` | 必需 | `"user"` | -| `source` | 必需 | [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) | - - - -### `packages/llm/llm/src/message.ts#UserMessage` - -SHA-256: `4de5e7644130ed715ef6b5a4d86a87b30dca4096d1a6683c66acf6f7809379c7` - -来源:[`packages/llm/llm/src/message.ts:143`](../packages/llm/llm/src/message.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `id` | 必需 | `string` | -| `role` | 必需 | `"user"` | -| `source` | 必需 | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | - - - -### `packages/llm/llm/src/types.ts#ContentBlock` - -SHA-256: `c7b24be059d34d08929593049a1a81eaa3855166aacfe9d7603c0bc8bb728d56` - -来源:[`packages/llm/llm/src/types.ts:137`](../packages/llm/llm/src/types.ts) - -以下类型之一: - -- [`packages/llm/llm/src/types.ts#ReasoningBlock`](#persistence-type-packagesllmllmsrctypestsreasoningblock) -- [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) -- [`packages/llm/llm/src/types.ts#ToolCallBlock`](#persistence-type-packagesllmllmsrctypeststoolcallblock) -- [`packages/llm/llm/src/types.ts#ImageBlock`](#persistence-type-packagesllmllmsrctypestsimageblock) -- [`packages/llm/llm/src/types.ts#FileBlock`](#persistence-type-packagesllmllmsrctypestsfileblock) -- [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) - - - -### `packages/llm/llm/src/types.ts#ContentBlockType` - -SHA-256: `757013fff5879d73d5753d8d1120faab56110e88ac3932485ab7e034d9e9ce61` - -来源:[`packages/llm/llm/src/types.ts:135`](../packages/llm/llm/src/types.ts) - -以下类型之一: - -- `"file"` -- `"image"` -- `"reasoning"` -- `"text"` -- `"tool-call"` -- `"tool-result"` - - - -### `packages/llm/llm/src/types.ts#FileBlock` - -SHA-256: `f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef` - -来源:[`packages/llm/llm/src/types.ts:97`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `attachment` | 必需 | [`packages/attachment/attachment/src/types.ts#FileAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsfileattachmentref) | -| `type` | 必需 | `"file"` | - - - -### `packages/llm/llm/src/types.ts#FinishReason` - -SHA-256: `5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80` - -来源:[`packages/llm/llm/src/types.ts:152`](../packages/llm/llm/src/types.ts) - -以下类型之一: - -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]`](#persistence-type-eventassistantattemptdatastream03chunk6reason3) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]`](#persistence-type-eventassistantattemptdatastream03chunk6reason4) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]`](#persistence-type-eventassistantattemptdatastream03chunk6reason0) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]`](#persistence-type-eventassistantattemptdatastream03chunk6reason1) -- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) - - - -### `packages/llm/llm/src/types.ts#ImageBlock` - -SHA-256: `12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7` - -来源:[`packages/llm/llm/src/types.ts:78`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `attachment` | 必需 | [`packages/attachment/attachment/src/types.ts#ImageAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsimageattachmentref) | -| `offloaded` | 可选 | `true` | -| `type` | 必需 | `"image"` | - - - -### `packages/llm/llm/src/types.ts#LlmFailure` - -SHA-256: `5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca` - -来源:[`packages/llm/llm/src/types.ts:40`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `code` | 必需 | `string` | -| `message` | 必需 | `string` | -| `offloadImages` | 可选 | `number` | -| `providerRetryAfterMs` | 可选 | `number` | -| `requestId` | 可选 | `string` | -| `status` | 可选 | `number` | - - - -### `packages/llm/llm/src/types.ts#ReasoningBlock` - -SHA-256: `814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e` - -来源:[`packages/llm/llm/src/types.ts:67`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `text` | 必需 | `string` | -| `type` | 必需 | `"reasoning"` | - - - -### `packages/llm/llm/src/types.ts#ReplayEnvelope` - -SHA-256: `0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555` - -来源:[`packages/llm/llm/src/types.ts:404`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `blocks` | 可选 | [`event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks`](#persistence-type-eventassistantattemptdatastream03chunk6replaystateblocks) | -| `response` | 必需 | `unknown`(不透明) | - - - -### `packages/llm/llm/src/types.ts#StreamChunk` - -SHA-256: `071d92b9dac661fcc826c678cf64d188f26fb93aab79c627b11a03acdd34dfca` - -来源:[`packages/llm/llm/src/types.ts:426`](../packages/llm/llm/src/types.ts) - -以下类型之一: - -- [`event:assistant/attempt.data.stream[0][3].chunk[3]`](#persistence-type-eventassistantattemptdatastream03chunk3) -- [`event:assistant/attempt.data.stream[0][3].chunk[4]`](#persistence-type-eventassistantattemptdatastream03chunk4) -- [`event:assistant/attempt.data.stream[0][3].chunk[0]`](#persistence-type-eventassistantattemptdatastream03chunk0) -- [`event:assistant/attempt.data.stream[0][3].chunk[2]`](#persistence-type-eventassistantattemptdatastream03chunk2) -- [`event:assistant/attempt.data.stream[0][3].chunk[1]`](#persistence-type-eventassistantattemptdatastream03chunk1) -- [`event:assistant/attempt.data.stream[0][3].chunk[6]`](#persistence-type-eventassistantattemptdatastream03chunk6) -- [`event:assistant/attempt.data.stream[0][3].chunk[5]`](#persistence-type-eventassistantattemptdatastream03chunk5) - - - -### `packages/llm/llm/src/types.ts#TokenUsage` - -SHA-256: `fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394` - -来源:[`packages/llm/llm/src/types.ts:162`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `cacheReadTokens` | 可选 | `number` | -| `cacheWriteTokens` | 可选 | `number` | -| `inputTokens` | 必需 | `number` | -| `outputTokens` | 必需 | `number` | -| `reasoningTokens` | 可选 | `number` | -| `totalTokens` | 可选 | `number` | - - - -### `packages/llm/llm/src/types.ts#ToolCallBlock` - -SHA-256: `c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea` - -来源:[`packages/llm/llm/src/types.ts:104`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `arguments` | 必需 | `string` | -| `id` | 必需 | `string` | -| `name` | 必需 | `string` | -| `type` | 必需 | `"tool-call"` | - - - -### `packages/llm/llm/src/types.ts#ToolResultBlock` - -SHA-256: `d61574d68558c5a184429e70b04da393dd5460bf5cc3ddef814546e659bd5127` - -来源:[`packages/llm/llm/src/types.ts:114`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | -| `isError` | 可选 | `boolean` | -| `toolCallId` | 必需 | `string` | -| `type` | 必需 | `"tool-result"` | - - - -### `packages/llm/llm/src/types.ts#ToolSchema` - -SHA-256: `7f5f2a8618c2ece530a18b1358b890fb57fb8c35705e47b66bff2296f8c6e889` - -来源:[`packages/llm/llm/src/types.ts:447`](../packages/llm/llm/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `description` | 必需 | `string` | -| `name` | 必需 | `string` | -| `parameters` | 必需 | [`event:request/header.data.header.tools[0].parameters`](#persistence-type-eventrequestheaderdataheadertools0parameters) | - - - -### `packages/sandbox/sandbox/src/index.ts#SandboxMode` - -SHA-256: `fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd` - -来源:[`packages/sandbox/sandbox/src/index.ts:29`](../packages/sandbox/sandbox/src/index.ts) - -以下类型之一: - -- `"danger-full-access"` -- `"read-only"` -- `"workspace-write"` - - - -### `packages/schedule/schedule/src/types.ts#AfterScheduleRecord` - -SHA-256: `27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe` - -来源:[`packages/schedule/schedule/src/types.ts:13`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `afterSeconds` | 必需 | `number` | -| `id` | 必需 | `string` | -| `kind` | 必需 | `"after"` | -| `prompt` | 必需 | `string` | -| `scheduledAt` | 必需 | `string` | - - - -### `packages/schedule/schedule/src/types.ts#AtScheduleRecord` - -SHA-256: `658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e` - -来源:[`packages/schedule/schedule/src/types.ts:27`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `id` | 必需 | `string` | -| `kind` | 必需 | `"at"` | -| `prompt` | 必需 | `string` | -| `scheduledAt` | 必需 | `string` | - - - -### `packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange` - -SHA-256: `e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344` - -来源:[`packages/schedule/schedule/src/types.ts:93`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `acceptedAt` | 必需 | `string` | -| `id` | 必需 | `string` | -| `operation` | 必需 | `"dispatch"` | -| `version` | 必需 | `1` | - - - -### `packages/schedule/schedule/src/types.ts#EveryScheduleRecord` - -SHA-256: `66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14` - -来源:[`packages/schedule/schedule/src/types.ts:39`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `everySeconds` | 必需 | `number` | -| `id` | 必需 | `string` | -| `kind` | 必需 | `"every"` | -| `prompt` | 必需 | `string` | -| `scheduledAt` | 必需 | `string` | - - - -### `packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange` - -SHA-256: `8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af` - -来源:[`packages/schedule/schedule/src/types.ts:86`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `id` | 必需 | `string` | -| `operation` | 必需 | `"dispatch"` | -| `version` | 必需 | `1` | - - - -### `packages/schedule/schedule/src/types.ts#ScheduleChange` - -SHA-256: `e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1` - -来源:[`packages/schedule/schedule/src/types.ts:105`](../packages/schedule/schedule/src/types.ts) - -以下类型之一: - -- [`packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestseveryscheduledispatchchange) -- [`packages/schedule/schedule/src/types.ts#ScheduleDeleteChange`](#persistence-type-packagesscheduleschedulesrctypestsscheduledeletechange) -- [`packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestsoneshotscheduledispatchchange) -- [`packages/schedule/schedule/src/types.ts#ScheduleCreateChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulecreatechange) - - - -### `packages/schedule/schedule/src/types.ts#ScheduleCreateChange` - -SHA-256: `ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f` - -来源:[`packages/schedule/schedule/src/types.ts:72`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `operation` | 必需 | `"create"` | -| `schedule` | 必需 | [`packages/schedule/schedule/src/types.ts#ScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsschedulerecord) | -| `version` | 必需 | `1` | - - - -### `packages/schedule/schedule/src/types.ts#ScheduleDeleteChange` - -SHA-256: `18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0` - -来源:[`packages/schedule/schedule/src/types.ts:79`](../packages/schedule/schedule/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `id` | 必需 | `string` | -| `operation` | 必需 | `"delete"` | -| `version` | 必需 | `1` | - - - -### `packages/schedule/schedule/src/types.ts#ScheduleRecord` - -SHA-256: `d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87` - -来源:[`packages/schedule/schedule/src/types.ts:69`](../packages/schedule/schedule/src/types.ts) - -以下类型之一: - -- [`packages/schedule/schedule/src/types.ts#AfterScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsafterschedulerecord) -- [`packages/schedule/schedule/src/types.ts#EveryScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestseveryschedulerecord) -- [`packages/schedule/schedule/src/types.ts#AtScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsatschedulerecord) - - - -### `packages/session/session-persistence-jsonl/src/format.ts#HeaderLine` - -SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` - -来源:[`packages/session/session-persistence-jsonl/src/format.ts:82`](../packages/session/session-persistence-jsonl/src/format.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `agentPreset` | 可选 | `string` | -| `createdAt` | 必需 | `number` | -| `cwd` | 可选 | `string` | -| `delegationDepth` | 必需 | `number` | -| `id` | 必需 | `string` | -| `isSeeded` | 必需 | `boolean` | -| `origin` | 可选 | `"subagent"` | -| `parentSession` | 可选 | `string` | -| `type` | 必需 | `"session"` | -| `version` | 必需 | `number` | - - - -### `packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData` - -SHA-256: `9fe0e77a7816b7fdb4b953ec0e2f0cd7bbd22c5de5c3567e612d1b20eb0992e6` - -来源:[`packages/session/session-title-llm/src/index.ts:27`](../packages/session/session-title-llm/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `maxTokens` | 必需 | `number` | -| `messageSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `messages` | 必需 | [`event:session/title-llm-request.data.messages`](#persistence-type-eventsessiontitle-llm-requestdatamessages) | -| `route` | 必需 | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | -| `system` | 必需 | `string` | -| `titleProvider` | 必需 | `string` | - - - -### `packages/session/session-title/src/types.ts#SessionTitleEventData` - -SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4` - -来源:[`packages/session/session-title/src/types.ts:41`](../packages/session/session-title/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `messageSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `source` | 必需 | [`packages/session/session-title/src/types.ts#SessionTitleSource`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlesource) | -| `title` | 必需 | `string` | - - - -### `packages/session/session-title/src/types.ts#SessionTitleModelIdentity` - -SHA-256: `07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235` - -来源:[`packages/session/session-title/src/types.ts:20`](../packages/session/session-title/src/types.ts) · [`packages/subagent/tool-subagent/src/model-selection.ts:9`](../packages/subagent/tool-subagent/src/model-selection.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `model` | 必需 | `string` | -| `provider` | 必需 | `string` | - - - -### `packages/session/session-title/src/types.ts#SessionTitleSource` - -SHA-256: `30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f` - -来源:[`packages/session/session-title/src/types.ts:28`](../packages/session/session-title/src/types.ts) - -以下类型之一: - -- [`event:session/title.data.source[1]`](#persistence-type-eventsessiontitledatasource1) -- [`event:session/title.data.source[0]`](#persistence-type-eventsessiontitledatasource0) -- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) - - - -### `packages/skill/skill/src/index.ts#SkillInvocationSource` - -SHA-256: `672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db` - -来源:[`packages/skill/skill/src/index.ts:146`](../packages/skill/skill/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"instructions"` | -| `kind` | 必需 | `"skill-invocation"` | -| `name` | 必需 | `string` | - - - -### `packages/skill/tool-skill/src/index.ts#SkillCatalogSource` - -SHA-256: `fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093` - -来源:[`packages/skill/tool-skill/src/index.ts:34`](../packages/skill/tool-skill/src/index.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `entries` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[17].entries`](#persistence-type-eventagentinboxspliceddatainserted0source17entries) | -| `form` | 必需 | `"catalog"` | -| `kind` | 必需 | `"skill-catalog"` | -| `update` | 可选 | `true` | - - - -### `packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent` - -SHA-256: `3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e` - -来源:[`packages/subagent/subagent/src/catalog.ts:24`](../packages/subagent/subagent/src/catalog.ts) - -以下类型之一: - -- [`event:subagent/catalog.data[1]`](#persistence-type-eventsubagentcatalogdata1) -- [`event:subagent/catalog.data[0]`](#persistence-type-eventsubagentcatalogdata0) - - - -### `packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource` - -SHA-256: `4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86` - -来源:[`packages/subagent/subagent/src/continuation-messages.ts:15`](../packages/subagent/subagent/src/continuation-messages.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"relay"` | -| `kind` | 必需 | `"agent-message"` | -| `senderSessionId` | 必需 | `string` | - - - -### `packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource` - -SHA-256: `4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a` - -来源:[`packages/subagent/subagent/src/continuation-messages.ts:30`](../packages/subagent/subagent/src/continuation-messages.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `form` | 必需 | `"notice"` | -| `kind` | 必需 | `"subagent-settled"` | -| `senderSessionId` | 必需 | `string` | -| `summary` | 必需 | `string` | - - - -### `packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData` - -SHA-256: `6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f` - -来源:[`packages/subagent/subagent/src/descriptor.ts:72`](../packages/subagent/subagent/src/descriptor.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `agentModel` | 可选 | `string` | -| `agentProvider` | 可选 | `string` | -| `agentReasoningEffort` | 可选 | `string` | -| `label` | 必需 | `string` | -| `mode` | 必需 | `"continuable"` | -| `persona` | 可选 | `string` | -| `provider` | 必需 | `string` | -| `toolFilter` | 可选 | [`packages/core/tools/src/index.ts#ToolRestriction`](#persistence-type-packagescoretoolssrcindextstoolrestriction) | -| `version` | 必需 | `number` | - - - -### `packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData` - -SHA-256: `5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564` - -来源:[`packages/subagent/subagent/src/descriptor.ts:61`](../packages/subagent/subagent/src/descriptor.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `label` | 可选 | `string` | -| `mode` | 必需 | `"one-shot"` | -| `provider` | 必需 | `string` | -| `version` | 必需 | `number` | - - - -### `packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData` - -SHA-256: `86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde` - -来源:[`packages/subagent/subagent/src/descriptor.ts:89`](../packages/subagent/subagent/src/descriptor.ts) - -以下类型之一: - -- [`packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortscontinuablesubagentdescriptordata) -- [`packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortsoneshotsubagentdescriptordata) - - - -### `packages/todo/tool-todo/src/types.ts#TodoItem` - -SHA-256: `a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a` - -来源:[`packages/todo/tool-todo/src/types.ts:21`](../packages/todo/tool-todo/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `content` | 必需 | `string` | -| `status` | 必需 | [`event:todo/write.data.todos[0].status`](#persistence-type-eventtodowritedatatodos0status) | - - - -### `packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest` - -SHA-256: `2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9` - -来源:[`packages/web/web-search-deepseek/src/provider.ts:55`](../packages/web/web-search-deepseek/src/provider.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `apiVersion` | 必需 | `string` | -| `body` | 必需 | [`event:web/deepseek-search-llm-request.data.body`](#persistence-type-eventwebdeepseek-search-llm-requestdatabody) | -| `endpoint` | 必需 | `string` | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData` - -SHA-256: `c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7` - -来源:[`packages/workflow/tool-workflow/src/types.ts:29`](../packages/workflow/tool-workflow/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `outcome` | 必需 | [`packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowagentoutcome) | -| `runId` | 必需 | `string` | -| `seq` | 必需 | `number` | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData` - -SHA-256: `9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc` - -来源:[`packages/workflow/tool-workflow/src/types.ts:20`](../packages/workflow/tool-workflow/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `childId` | 必需 | `string` | -| `label` | 必需 | `string` | -| `phase` | 可选 | `string` | -| `runId` | 必需 | `string` | -| `seq` | 必需 | `number` | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData` - -SHA-256: `7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462` - -来源:[`packages/workflow/tool-workflow/src/types.ts:36`](../packages/workflow/tool-workflow/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `runId` | 必需 | `string` | -| `stopReason` | 必需 | [`packages/workflow/workflow/src/types.ts#WorkflowStopReason`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowstopreason) | - - - -### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData` - -SHA-256: `a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c` - -来源:[`packages/workflow/tool-workflow/src/types.ts:14`](../packages/workflow/tool-workflow/src/types.ts) - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `name` | 必需 | `string` | -| `runId` | 必需 | `string` | - - - -### `packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome` - -SHA-256: `c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896` - -来源:[`packages/workflow/workflow/src/types.ts:110`](../packages/workflow/workflow/src/types.ts) - -以下类型之一: - -- `"cancelled"` -- `"completed"` -- `"failed"` - - - -### `packages/workflow/workflow/src/types.ts#WorkflowStopReason` - -SHA-256: `8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15` - -来源:[`packages/workflow/workflow/src/types.ts:63`](../packages/workflow/workflow/src/types.ts) - -以下类型之一: - -- `"cancelled"` -- `"completed"` -- `"error"` - - - -### `"parent"` - -SHA-256: `e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732` - -`"parent"` - - - -### `"pause"` - -SHA-256: `1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721` - -`"pause"` - - - -### `"paused"` - -SHA-256: `c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943` - -`"paused"` - - - -### `"pending"` - -SHA-256: `234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85` - -`"pending"` - - - -### `"permission/preset"` - -SHA-256: `ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649` - -`"permission/preset"` - - - -### `"plan/mode"` - -SHA-256: `f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9` - -`"plan/mode"` - - - -### `"plugin"` - -SHA-256: `e654d28d1e6c471147310d2fba396d00969cfe6ed9022626d3f2c2312e0b1cbb` - -`"plugin"` - - - -### `"positive"` - -SHA-256: `df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528` - -`"positive"` - - - -### `"product-interaction"` - -SHA-256: `0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23` - -`"product-interaction"` - - - -### `"provider"` - -SHA-256: `e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a` - -`"provider"` - - - -### `"provisioning"` - -SHA-256: `871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62` - -`"provisioning"` - - - -### `"read-only"` - -SHA-256: `12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42` - -`"read-only"` - - - -### `"reasoning"` - -SHA-256: `3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c` - -`"reasoning"` - - - -### `"reasoning-chunks"` - -SHA-256: `688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8` - -`"reasoning-chunks"` - - - -### `"reasoning-delta"` - -SHA-256: `6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6` - -`"reasoning-delta"` - - - -### `"recall"` - -SHA-256: `383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f` - -`"recall"` - - - -### `"rejected"` - -SHA-256: `fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018` - -`"rejected"` - - - -### `"relay"` - -SHA-256: `16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e` - -`"relay"` - - - -### `"remove"` - -SHA-256: `7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc` - -`"remove"` - - - -### `"replace"` - -SHA-256: `f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8` - -`"replace"` - - - -### `"request/context"` - -SHA-256: `70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2` - -`"request/context"` - - - -### `"request/header"` - -SHA-256: `3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e` - -`"request/header"` - - - -### `"resource-cost"` - -SHA-256: `5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75` - -`"resource-cost"` - - - -### `"resume"` - -SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66` - -`"resume"` - - - -### `"sandbox/mode"` - -SHA-256: `ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2` - -`"sandbox/mode"` - - - -### `"schedule/change"` - -SHA-256: `0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d` - -`"schedule/change"` - - - -### `"security-privacy-permission"` - -SHA-256: `07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7` - -`"security-privacy-permission"` - - - -### `"series"` - -SHA-256: `4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f` - -`"series"` - - - -### `"service-stability"` - -SHA-256: `7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732` - -`"service-stability"` - - - -### `"session"` - -SHA-256: `e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828` - -`"session"` - - - -### `"session-log-deepseek/delivery-accepted"` - -SHA-256: `47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b` - -`"session-log-deepseek/delivery-accepted"` - - - -### `"session-reference"` - -SHA-256: `7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71` - -`"session-reference"` - - - -### `"session/end-seed"` - -SHA-256: `1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330` - -`"session/end-seed"` - - - -### `SessionEventEnvelope` - -SHA-256: `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` - -以下类型之一: - -- [`SessionEventEnvelope[39]`](#persistence-type-sessioneventenvelope39) -- [`SessionEventEnvelope[6]`](#persistence-type-sessioneventenvelope6) -- [`SessionEventEnvelope[0]`](#persistence-type-sessioneventenvelope0) - - - -### `SessionEventEnvelope[0]` - -SHA-256: `e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `time` | 必需 | `number` | -| `type` | 必需 | `string` | - - - -### `SessionEventEnvelope[39]` - -SHA-256: `998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0` - -| 属性 | 存在性 | 类型 | -|---|---|---| -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | -| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | 必需 | `number` | -| `type` | 必需 | `string` | - - - -### `SessionEventEnvelope[39].sourceEventSeqs` - -SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` - -`number` 的数组。 - - - -### `SessionEventEnvelope[6]` - -SHA-256: `7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb` +SHA-256: `0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f` | 属性 | 存在性 | 类型 | |---|---|---| -| `ignorable` | 可选 | `true` | -| `seq` | 必需 | `number` | -| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | -| `time` | 必需 | `number` | -| `type` | 必需 | `string` | +| [`string`] | 索引签名 | `unknown`(不透明) | - + -### `SessionEventEnvelope[6].surfaceOp[1]` +### `{}` -SHA-256: `bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825` +SHA-256: `529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05` -来源:[`packages/core/session/src/types.ts:441`](../packages/core/session/src/types.ts) +来源:[`packages/util/values/src/index.ts:4`](../packages/util/values/src/index.ts) | 属性 | 存在性 | 类型 | |---|---|---| -| `endSeq` | 必需 | `number` | -| `op` | 必需 | `"replace"` | -| `startSeq` | 必需 | `number` | - - - -### `"session/title"` - -SHA-256: `7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50` - -`"session/title"` - - - -### `"session/title-llm-request"` - -SHA-256: `587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e` - -`"session/title-llm-request"` - - - -### `"set"` - -SHA-256: `b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b` - -`"set"` - - - -### `"skill-catalog"` - -SHA-256: `6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3` - -`"skill-catalog"` - - - -### `"skill-invocation"` - -SHA-256: `1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509` - -`"skill-invocation"` - - - -### `"snapshot"` - -SHA-256: `6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912` - -`"snapshot"` - - - -### `"step/end"` - -SHA-256: `c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70` - -`"step/end"` - - - -### `"step/start"` - -SHA-256: `2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d` - -`"step/start"` - - - -### `"stop"` - -SHA-256: `57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90` - -`"stop"` - - - -### `string` - -SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` - -来源:[`packages/api/session-controller/src/types.ts:376`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:19`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:10`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/webhook/webhook/src/brand.ts:12`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:6`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:9`](../packages/webhook/webhook/src/brand.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) - -`string` - - - -### `"subagent"` - -SHA-256: `aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6` - -`"subagent"` - - - -### `"subagent-settled"` - -SHA-256: `bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a` - -`"subagent-settled"` - - - -### `"subagent/catalog"` - -SHA-256: `44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2` - -`"subagent/catalog"` - - - -### `"subagent/descriptor"` - -SHA-256: `5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647` - -`"subagent/descriptor"` - - - -### `"subagent/model-selection-policy"` - -SHA-256: `0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da` - -`"subagent/model-selection-policy"` - - - -### `"success"` - -SHA-256: `511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7` - -`"success"` - - - -### `"system"` - -SHA-256: `8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3` - -`"system"` - - - -### `"system/message"` - -SHA-256: `1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7` - -`"system/message"` - - - -### `"task-result"` - -SHA-256: `f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c` - -`"task-result"` - - - -### `"team-message"` - -SHA-256: `2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c` - -`"team-message"` - - - -### `"team/member"` - -SHA-256: `18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0` - -`"team/member"` - - - -### `"team/message/delivered"` - -SHA-256: `a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57` - -`"team/message/delivered"` - - - -### `"team/message/queued"` - -SHA-256: `4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159` - -`"team/message/queued"` - - - -### `"team/task"` - -SHA-256: `b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b` - -`"team/task"` - - - -### `"text"` - -SHA-256: `4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d` - -`"text"` - - - -### `"text-chunks"` - -SHA-256: `f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3` - -`"text-chunks"` - - - -### `"text-delta"` - -SHA-256: `5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563` - -`"text-delta"` - - - -### `"todo/write"` - -SHA-256: `af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7` - -`"todo/write"` - - - -### `"tool"` - -SHA-256: `a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847` - -`"tool"` - - - -### `"tool-call"` - -SHA-256: `1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7` - -`"tool-call"` - - - -### `"tool-call-chunks"` - -SHA-256: `616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5` - -`"tool-call-chunks"` - - - -### `"tool-call-delta"` - -SHA-256: `9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267` - -`"tool-call-delta"` - - - -### `"tool-calls"` - -SHA-256: `6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b` - -`"tool-calls"` - - - -### `"tool-result"` - -SHA-256: `e5244812c495a80c2e78ba2c2690dca5f6b58ea8d3fe5531ff94a6f9ac5e5d66` - -`"tool-result"` - - - -### `"tool-workflow/agent-end"` - -SHA-256: `5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e` - -`"tool-workflow/agent-end"` - - - -### `"tool-workflow/agent-start"` - -SHA-256: `ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8` - -`"tool-workflow/agent-start"` - - - -### `"tool-workflow/run-end"` - -SHA-256: `fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd` - -`"tool-workflow/run-end"` - - - -### `"tool-workflow/run-start"` - -SHA-256: `cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670` - -`"tool-workflow/run-start"` - - - -### `"tool/call"` - -SHA-256: `c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92` - -`"tool/call"` - - - -### `"tool/ptc-dispatch"` - -SHA-256: `fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973` - -`"tool/ptc-dispatch"` - - - -### `"tool/ptc-dispatch-start"` - -SHA-256: `2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456` - -`"tool/ptc-dispatch-start"` - - - -### `"tool/result"` - -SHA-256: `570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833` - -`"tool/result"` - - - -### `true` - -SHA-256: `dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521` - -`true` - - - -### `"turn/end"` - -SHA-256: `4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03` - -`"turn/end"` - - - -### `"turn/start"` - -SHA-256: `0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f` - -`"turn/start"` - - - -### `"unavailable"` - -SHA-256: `2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c` - -`"unavailable"` - - - -### `unknown` - -SHA-256: `bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d` - -`unknown`:此声明未暴露存储值的内部字段。 - - - -### `"usage"` - -SHA-256: `0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9` - -`"usage"` - - - -### `"user"` - -SHA-256: `68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573` - -`"user"` - - - -### `"user/message"` - -SHA-256: `de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f` - -`"user/message"` - - - -### `"web_search"` - -SHA-256: `935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682` - -`"web_search"` - - - -### `"web_search_20250305"` - -SHA-256: `0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e` - -`"web_search_20250305"` - - - -### `"web/deepseek-search-llm-request"` - -SHA-256: `6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675` - -`"web/deepseek-search-llm-request"` - - - -### `"webhook"` - -SHA-256: `db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0` - -`"webhook"` - - - -### `"workspace-write"` - -SHA-256: `a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa` - -`"workspace-write"` - - - -### `"workspace/changes"` - -SHA-256: `8e8155594e07812356b67d732196dda894b0f9c91a5969d51612cf490b0a016d` - -`"workspace/changes"` +| [`string`] | 索引签名 | [`JsonValue`](#persistence-type-sha256-c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6) | diff --git a/docs/persistence-changes/2026-09-16-session-format-v4.i18n.yaml b/docs/persistence-changes/2026-09-16-session-format-v4.i18n.yaml new file mode 100644 index 0000000000..b90b3160e5 --- /dev/null +++ b/docs/persistence-changes/2026-09-16-session-format-v4.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write docs/persistence-changes/2026-09-16-session-format-v4.md +2026-09-16-session-format-v4.md: 187acab093b319856ed9971da3ddac08bc02c06f +2026-09-16-session-format-v4.zh.md: 16a17937979ea5a02d7ede9282183a10e879cde7 diff --git a/docs/persistence-changes/2026-09-16-session-format-v4.md b/docs/persistence-changes/2026-09-16-session-format-v4.md new file mode 100644 index 0000000000..187acab093 --- /dev/null +++ b/docs/persistence-changes/2026-09-16-session-format-v4.md @@ -0,0 +1,120 @@ +--- +description: "Records a persistence type transition and its compatibility acknowledgement." +kind: persistence-change +--- + +# 2026-09-16-session-format-v4 + +English | [中文](2026-09-16-session-format-v4.zh.md) + +## Summary + +Advances the declared SessionHeader.version from 3 to 4 for the finalized V4 writer, records first-class tool-role results and producer-owned sources, and adds the forked variant to turn/end.reason. Adds developer-role Session changes with name-only tool additions bound to historical request headers, tool removals, and deferred-loading schema markers. + +## Table of Contents + +- [Declaration](#declaration) +- [Compatibility](#compatibility) +- [Verification](#verification) +- [Dev Note](#dev-note) + + +## Declaration + +```yaml persistence-change +schemaVersion: 1 +id: 2026-09-16-session-format-v4 +baseline: false +changes: + - root: "SessionHeader" + previous: "2026-09-11-initial" + after: "1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445" + decision: version-bump + - root: "event:agent/inbox/spliced" + previous: "2026-09-14-image-offload" + after: "1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c" + decision: version-bump + - root: "event:assistant/attempt" + previous: "2026-09-14-image-offload" + after: "15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4" + decision: version-bump + - root: "event:assistant/message" + previous: "2026-09-14-image-offload" + after: "1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625" + decision: version-bump + - root: "event:compaction/summary" + previous: "2026-09-14-image-offload" + after: "e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602" + decision: version-bump + - root: "event:developer/message" + previous: null + after: "eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80" + decision: version-bump + - root: "event:request/header" + previous: "2026-09-11-initial" + after: "4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41" + decision: version-bump + - root: "event:session/title-llm-request" + previous: "2026-09-14-image-offload" + after: "fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d" + decision: version-bump + - root: "event:system/message" + previous: "2026-09-14-image-offload" + after: "69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1" + decision: version-bump + - root: "event:team/message/queued" + previous: "2026-09-14-image-offload" + after: "21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d" + decision: version-bump + - root: "event:tool/ptc-dispatch" + previous: "2026-09-14-image-offload" + after: "100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163" + decision: version-bump + - root: "event:tool/result" + previous: "2026-09-14-image-offload" + after: "7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397" + decision: version-bump + - root: "event:turn/end" + previous: "2026-09-14-image-offload" + after: "0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce" + decision: version-bump + - root: "event:user/message" + previous: "2026-09-14-image-offload" + after: "3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761" + decision: version-bump +``` + + +## Compatibility + +The tool-role declaration changes ten event roots because inbox entries, message events, compaction summaries, title requests, team messages, and PTC dispatches embed the shared `Message` or `ContentBlock` declarations. Removing `tool-result` from that union and specializing message roles changes those reachable schemas without adding ten independent event protocols. The `turn/end` change separately records the forked reason; `SessionHeader` records the version increase. + +The [native V4 validation decision](../../.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.md) owns the reader admission required by these current fields. + +The V3-to-V4 migration lifts released user-role tool results into tool-role messages with a required toolCallId and optional isError. Tool-result wrappers leave the content-block union. The migration preserves every admitted source event and inherited cut, and appends missing parent subagent/catalog records from retained direct-child logs in the same persistence root. Historical body restoration requires an explicit child-evidence set, including an empty set when no children are available to backfill. Missing, multiple, or unknown-version child descriptors skip that child’s backfill; conflicting identities, timestamps, or modes refuse migration without publication. Existing catalog facts remain. Historical read opens prepare the result in memory. Write opens revalidate child membership and revisions before publishing the current successor beside unchanged predecessor files. Delivery-generation checks keep historical acknowledgements from becoming active V4 watermarks. V3 readers refuse the newer generation. The finalized transition adds forked to turn/end.reason; exact-cut forks append child-owned error results and closers after the inherited marker. V4 admits checked not-started fork results with deterministic branch-specific IDs and wording; released V0–V3 validators and recorded predecessor generations remain unchanged. + +The `request/header` schema also records the retired `system` key as forbidden. This declaration captures the existing native-reader refusal without changing stored data or prompt reconstruction; later permitting a value requires a version bump instead of being classified as an ordinary optional-field addition. + +Producer-owned sources replace released plugin wrappers through the [V3-to-V4 migration](../../packages/session/session-format-v3-to-v4/README.md#v3-to-v4-specification). The frozen rename table and collision rules preserve source fields and event coordinates; unknown producer attribution retains every own JSON property. Native read and write opens validate source fields before exposing the Session. Existing V4 files do not rerun the incoming migration edge. + +The core-owned user source property records the attribution-preservation policy; tmux-context qualifies its location attribution while retaining producer-local duplicate suppression. Auto Review and the compaction summarizer use request-only user inputs, removing their active source registrations without removing historical migration support. These inputs cannot be written as durable Session messages. Catalog formatVersion 2 stores the policy metadata; it does not change the Session version or rewrite frozen schema records. System, model, and tool sources retain their strict semantic rules. + +Developer events retain their original role and require an open step. Each addition stores toolName; developer/message.headerSeq identifies an earlier known request/header containing exactly one complete matching ToolSchema. All additions in one event share that historical header revision, while removal-only and other developer messages omit headerSeq. Native and Session admission reject absent, forward, non-header, unknown-header, ambiguous, incomplete-definition and retired inline-definition forms without interpreting unknown ignorable records or dropping unrelated JSON metadata. Same-name replacement, restart, fork, surface replacement and compaction retain historical schema identity without consulting the latest header or registry. Generic sourceEventSeqs remains independent. Developer sources use the same recorded attribution-preservation policy as user sources. The optional deferLoading marker is independent of addition history. No shipped profile emits developer records; provider serialization, automatic emission and UI support remain deferred. + +The PTC producer writes `source.kind: 'ptc-mode'`. The V3-to-V4 edge retains `tools-code-mode` and `tools-ptc` as historical plugin lookup keys and maps both to that current kind. The source policy reserves `ptc-mode` against attribution-only qualification. + + +## Verification + +The focused Session, agent-loop, Session Controller, V4, chat-view, and compaction suites passed 1,523 tests across 63 files after integration of exact-cut forks. V4 fork tests retain original IDs and text across encoding, decoding, and restoration, reject malformed results, and validate nested inherited cuts. The tool-role migration tests and SDK snapshot refresh also passed in the originating change; the built Python runtime sdk-snapshot scenario passed, and focused pi-ai and auto-review coverage passed 351 tests with 100% coverage of the three affected modules. + +The generated request-header reservation regression and existing retired-syntax and Session surface tests pass 65 tests across three files. The generated field retains optional `never`; permitting an optional string produces a version-bump diagnostic while the native reader still refuses the retired key. + +The producer-source and request-input checks pass 447 tests across 12 files, including provider equality, request-only type rejection, user-attribution retention, source migration, and native source admission. Comparing the generated inventories with the tool-role parent reports four changed roots and 447 unchanged type fingerprints. + +The focused Session, V4 and request-input suite passes 884 tests across 38 files, with 100% statements, branches, functions and lines for the complete V3-to-V4 package and Session surface. Coverage includes historical same-name schema binding, compound additions/removals, malformed references and definitions, unknown-header refusal, opaque unknown records, metadata preservation, forks, replacements, compaction references, and native plain/zstd read/write admission without rewriting the generation. + + +## Dev Note + +None. diff --git a/docs/persistence-changes/2026-09-16-session-format-v4.schema.json b/docs/persistence-changes/2026-09-16-session-format-v4.schema.json new file mode 100644 index 0000000000..b2d767e122 --- /dev/null +++ b/docs/persistence-changes/2026-09-16-session-format-v4.schema.json @@ -0,0 +1,16212 @@ +{ + "formatVersion": 2, + "roots": [ + { + "key": "SessionHeader", + "kind": "header", + "digest": "1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 2, + "optional": false + }, + { + "name": "cwd", + "type": 1, + "optional": true + }, + { + "name": "delegationDepth", + "type": 2, + "optional": true + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "isSeeded", + "type": 3, + "optional": false + }, + { + "name": "origin", + "type": 4, + "optional": true + }, + { + "name": "parentSession", + "type": 1, + "optional": true + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "subagent" + }, + { + "kind": "literal", + "value": 4 + } + ] + } + }, + { + "key": "event:agent/inbox/spliced", + "kind": "event", + "event": "agent/inbox/spliced", + "surface": false, + "digest": "1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 27, + "optional": true + }, + { + "name": "seq", + "type": 20, + "optional": false + }, + { + "name": "time", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 199, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "inserted", + "type": 2, + "optional": false + }, + { + "name": "outcome", + "type": 195, + "optional": true + }, + { + "name": "removedCount", + "type": 20, + "optional": true + }, + { + "name": "start", + "type": 20, + "optional": false + }, + { + "name": "target", + "type": 196, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 32, + "optional": false + }, + { + "name": "source", + "type": 33, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 14, + 16, + 18, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 27, + "optional": true + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "mediaType", + "type": 21, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 26, + "optional": true + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 22, + 23, + 24, + 25 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 30, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 34, + 37, + 39, + 41, + 43, + 45, + 47, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 112, + 114, + 117, + 118, + 119, + 120, + 121, + 123, + 124, + 125, + 126, + 128, + 129, + 130, + 131, + 132, + 134, + 135, + 136, + 138, + 139, + 147, + 149, + 150, + 152, + 154, + 158, + 160, + 168, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 186, + 188, + 189, + 190, + 191, + 192, + 193, + 194 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 111, + "optional": false + }, + { + "name": "revision", + "type": 20, + "optional": false + }, + { + "name": "round", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 113, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 115, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 116, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 122, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 127, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 133, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 137, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 27, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 140, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 141 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 142, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 143, + 144, + 145 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 155, + "optional": false + }, + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 157, + "optional": false + }, + { + "name": "update", + "type": 27, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "references", + "type": 162, + "optional": false + }, + { + "name": "version", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 163 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 20, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 164, + "optional": false + }, + { + "name": "compacted", + "type": 166, + "optional": false + }, + { + "name": "inputIndex", + "type": 20, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 20, + "optional": false + }, + { + "name": "omittedMessages", + "type": 20, + "optional": false + }, + { + "name": "originalMessages", + "type": 20, + "optional": false + }, + { + "name": "retainedMessages", + "type": 20, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 166, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 165 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 171 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 185, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 187, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "canceled" + }, + { + "kind": "union", + "types": [ + 197, + 198 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + }, + { + "kind": "literal", + "value": "agent/inbox/spliced" + } + ] + } + }, + { + "key": "event:assistant/attempt", + "kind": "event", + "event": "assistant/attempt", + "surface": false, + "digest": "15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "stream", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 10, + 69, + 71 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 6, + "optional": false + }, + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 68, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 12, + 14, + 41, + 44, + 46, + 48, + 65 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 15, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 16, + 18, + 28, + 31, + 33, + 35, + 38 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 36, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 42, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 27, + 30, + 32, + 34, + 37, + 39 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 49, + "optional": false + }, + { + "name": "replayState", + "type": 61, + "optional": true + }, + { + "name": "type", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 50, + 53, + 55, + 57, + 59 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 51, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 2, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 2, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 51, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 62, + "optional": true + }, + { + "name": "response", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 63 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 66, + "optional": false + }, + { + "name": "usage", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 2, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 2, + "optional": true + }, + { + "name": "inputTokens", + "type": 2, + "optional": false + }, + { + "name": "outputTokens", + "type": 2, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 2, + "optional": true + }, + { + "name": "totalTokens", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "literal", + "value": "assistant/attempt" + } + ] + } + }, + { + "key": "event:assistant/message", + "kind": "event", + "event": "assistant/message", + "surface": true, + "digest": "1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "surfaceOp", + "type": 78, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "interrupted", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 11, + "optional": false + }, + { + "name": "stream", + "type": 35, + "optional": false + }, + { + "name": "turn", + "type": 11, + "optional": false + }, + { + "name": "usage", + "type": 72, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 19, + 22, + 24, + 26, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 2, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 34, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 36 + }, + { + "kind": "union", + "types": [ + 37, + 41, + 74, + 76 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 38, + "optional": false + }, + { + "name": "dt", + "type": 39, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "array", + "element": 11 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 42, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 43, + 45, + 47, + 50, + 52, + 54, + 70 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 5, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 48, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 23, + 25, + 28, + 30 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 55, + "optional": false + }, + { + "name": "replayState", + "type": 67, + "optional": true + }, + { + "name": "type", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 56, + 59, + 61, + 63, + 65 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 57, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 11, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 11, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 11, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 57, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 68, + "optional": true + }, + { + "name": "response", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 71, + "optional": false + }, + { + "name": "usage", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 11, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 11, + "optional": true + }, + { + "name": "inputTokens", + "type": 11, + "optional": false + }, + { + "name": "outputTokens", + "type": 11, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 11, + "optional": true + }, + { + "name": "totalTokens", + "type": 11, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 39, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 38, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 39, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 38, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 77, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "union", + "types": [ + 79, + 81 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 11, + "optional": false + }, + { + "name": "op", + "type": 80, + "optional": false + }, + { + "name": "startSeq", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "literal", + "value": "assistant/message" + } + ] + } + }, + { + "key": "event:compaction/summary", + "kind": "event", + "event": "compaction/summary", + "surface": false, + "digest": "e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 34 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 4, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": false + }, + { + "name": "shadowedRange", + "type": 31, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 32, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 33, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 10, + 12, + 15, + 17, + 19, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 13, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "offloaded", + "type": 4, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "mediaType", + "type": 21, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 26, + "optional": true + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 22, + 23, + 24, + 25 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 5, + "optional": false + }, + { + "name": "start", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 5, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 5, + "optional": true + }, + { + "name": "inputTokens", + "type": 5, + "optional": false + }, + { + "name": "outputTokens", + "type": 5, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 5, + "optional": true + }, + { + "name": "totalTokens", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": true + }, + { + "name": "shadowedRange", + "type": 31, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 32, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 33, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compaction/summary" + } + ] + } + }, + { + "key": "event:developer/message", + "kind": "event", + "event": "developer/message", + "surface": true, + "digest": "eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 195, + "optional": true + }, + { + "name": "surfaceOp", + "type": 196, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 199, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "headerSeq", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 14, + 16, + 18, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 33, + 36, + 38, + 40, + 42, + 44, + 46, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 111, + 113, + 116, + 117, + 118, + 119, + 120, + 122, + 123, + 124, + 125, + 127, + 128, + 129, + 130, + 131, + 133, + 135, + 136, + 138, + 139, + 147, + 149, + 150, + 152, + 154, + 158, + 160, + 168, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 186, + 188, + 189, + 190, + 191, + 192, + 193, + 194 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 110, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 112, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 114, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 115, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 121, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 126, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 132, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 137, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 26, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 140, + "optional": false + }, + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 141 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 142, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 143, + 144, + 145 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 134, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 155, + "optional": false + }, + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 157, + "optional": false + }, + { + "name": "update", + "type": 26, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "references", + "type": 162, + "optional": false + }, + { + "name": "version", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 163 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 164, + "optional": false + }, + { + "name": "compacted", + "type": 166, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 166, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 165 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 171 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 185, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 187, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 197, + 198 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 2, + "optional": false + }, + { + "name": "op", + "type": 144, + "optional": false + }, + { + "name": "startSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer/message" + } + ] + } + }, + { + "key": "event:request/header", + "kind": "event", + "event": "request/header", + "surface": false, + "digest": "4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "header", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 14, + "optional": false + }, + { + "name": "startsSeries", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 3, + "optional": true + }, + { + "name": "config", + "type": 5, + "optional": false + }, + { + "name": "system", + "type": 9, + "optional": true + }, + { + "name": "tools", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 6, + "optional": true + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 7, + "optional": true + }, + { + "name": "stop", + "type": 8, + "optional": true + }, + { + "name": "temperature", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "array", + "element": 11 + }, + { + "kind": "object", + "properties": [ + { + "name": "deferLoading", + "type": 4, + "optional": true + }, + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "parameters", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 7, + "value": 13 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "union", + "types": [ + 15, + 16, + 17, + 18 + ] + }, + { + "kind": "literal", + "value": "initial" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "series" + }, + { + "kind": "literal", + "value": "change" + }, + { + "kind": "literal", + "value": "request/header" + } + ] + } + }, + { + "key": "event:session/title-llm-request", + "kind": "event", + "event": "session/title-llm-request", + "surface": false, + "digest": "fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 29, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 205, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 2, + "optional": false + }, + { + "name": "messageSeqs", + "type": 3, + "optional": false + }, + { + "name": "messages", + "type": 4, + "optional": false + }, + { + "name": "route", + "type": 204, + "optional": false + }, + { + "name": "system", + "type": 10, + "optional": false + }, + { + "name": "titleProvider", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 37, + 199, + 200, + 202 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "isError", + "type": 34, + "optional": true + }, + { + "name": "role", + "type": 35, + "optional": false + }, + { + "name": "source", + "type": 36, + "optional": false + }, + { + "name": "toolCallId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 8 + }, + { + "kind": "union", + "types": [ + 9, + 12, + 14, + 17, + 19, + 21, + 31 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 15, + "optional": true + }, + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 10, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 22, + "optional": false + }, + { + "name": "offloaded", + "type": 29, + "optional": true + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 10, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 23, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": true + }, + { + "name": "originalDimensions", + "type": 28, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 24, + 25, + 26, + 27 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 32, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 10, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 38, + "optional": false + }, + { + "name": "source", + "type": 39, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 36, + 40, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 70, + 72, + 74, + 76, + 78, + 80, + 85, + 87, + 95, + 100, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 142, + 143, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 174, + 175, + 177, + 180, + 181, + 182, + 183, + 184, + 186, + 187, + 188, + 189, + 190, + 192, + 193, + 194, + 195, + 196, + 198 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 29, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 10, + "optional": true + }, + { + "name": "changes", + "type": 62, + "optional": false + }, + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 63 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 64, + "optional": false + }, + { + "name": "digest", + "type": 10, + "optional": true + }, + { + "name": "path", + "type": 10, + "optional": false + }, + { + "name": "scope", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 65, + 66, + 67 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 10, + "optional": true + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "rpcId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 10, + "optional": false + }, + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 77, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + }, + { + "name": "ruleId", + "type": 10, + "optional": false + }, + { + "name": "source", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 81, + "optional": false + }, + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 84, + "optional": false + }, + { + "name": "update", + "type": 29, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 82 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 86, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 89, + "optional": false + }, + { + "name": "references", + "type": 90, + "optional": false + }, + { + "name": "version", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 91 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 92, + "optional": false + }, + { + "name": "compacted", + "type": 34, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 10, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 10, + "optional": false + }, + { + "name": "truncated", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 93 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "array", + "element": 99 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 141, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 162, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 173, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 176, + "optional": false + }, + { + "name": "messageId", + "type": 10, + "optional": false + }, + { + "name": "senderId", + "type": 10, + "optional": false + }, + { + "name": "senderName", + "type": 10, + "optional": false + }, + { + "name": "teamId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 178, + "optional": false + }, + { + "name": "model", + "type": 10, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + }, + { + "name": "replayState", + "type": 179, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 185, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 191, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 197, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 71, + "optional": false + }, + { + "name": "source", + "type": 39, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 201, + "optional": false + }, + { + "name": "source", + "type": 177, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 203, + "optional": false + }, + { + "name": "source", + "type": 190, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 10, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session/title-llm-request" + } + ] + } + }, + { + "key": "event:system/message", + "kind": "event", + "event": "system/message", + "surface": true, + "digest": "69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 17, + "optional": true + }, + { + "name": "seq", + "type": 10, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 34, + "optional": true + }, + { + "name": "surfaceOp", + "type": 35, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 10, + "optional": false + }, + { + "name": "turn", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 19, + 22, + 24, + 26, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "union", + "types": [ + 36, + 38 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 10, + "optional": false + }, + { + "name": "op", + "type": 37, + "optional": false + }, + { + "name": "startSeq", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "literal", + "value": "system/message" + } + ] + } + }, + { + "key": "event:team/message/queued", + "kind": "event", + "event": "team/message/queued", + "surface": false, + "digest": "21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 19, + "optional": false + }, + { + "name": "time", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "targetId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 13, + 15, + 17, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": "team/message/queued" + } + ] + } + }, + { + "key": "event:tool/ptc-dispatch", + "kind": "event", + "event": "tool/ptc-dispatch", + "surface": false, + "digest": "100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 19, + "optional": false + }, + { + "name": "time", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "error", + "type": 31, + "optional": true + }, + { + "name": "isError", + "type": 32, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "parentCallId", + "type": 6, + "optional": false + }, + { + "name": "rootCallId", + "type": 6, + "optional": false + }, + { + "name": "subCallId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 13, + 15, + 17, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "reason", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool/ptc-dispatch" + } + ] + } + }, + { + "key": "event:tool/result", + "kind": "event", + "event": "tool/result", + "surface": true, + "digest": "7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 27, + "optional": true + }, + { + "name": "seq", + "type": 20, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 39, + "optional": true + }, + { + "name": "surfaceOp", + "type": 40, + "optional": false + }, + { + "name": "time", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "meta", + "type": 35, + "optional": true + }, + { + "name": "step", + "type": 20, + "optional": false + }, + { + "name": "turn", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "reason", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 32, + "optional": true + }, + { + "name": "role", + "type": 33, + "optional": false + }, + { + "name": "source", + "type": 34, + "optional": false + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "union", + "types": [ + 7, + 9, + 11, + 14, + 16, + 18, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 27, + "optional": true + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "mediaType", + "type": 21, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 26, + "optional": true + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 22, + 23, + 24, + 25 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 30, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 20, + 32, + 36, + 37, + 38 + ] + }, + { + "kind": "array", + "element": 35 + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 35 + } + ] + }, + { + "kind": "array", + "element": 20 + }, + { + "kind": "union", + "types": [ + 41, + 42 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 20, + "optional": false + }, + { + "name": "op", + "type": 43, + "optional": false + }, + { + "name": "startSeq", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "tool/result" + } + ] + } + }, + { + "key": "event:turn/end", + "kind": "event", + "event": "turn/end", + "surface": false, + "digest": "0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 31, + "optional": true + }, + { + "name": "seq", + "type": 16, + "optional": false + }, + { + "name": "time", + "type": 16, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 5, + 7, + 9, + 11, + 13, + 18 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "forked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 14, + "optional": false + }, + { + "name": "kind", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 15, + "optional": false + }, + { + "name": "message", + "type": 15, + "optional": false + }, + { + "name": "offloadImages", + "type": 16, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 16, + "optional": true + }, + { + "name": "requestId", + "type": 15, + "optional": true + }, + { + "name": "status", + "type": 16, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 19, + "optional": false + }, + { + "name": "reason", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 21, + 23, + 25, + 27, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + }, + { + "name": "reason", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "turn/end" + } + ] + } + }, + { + "key": "event:user/message", + "kind": "event", + "event": "user/message", + "surface": true, + "digest": "3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 25, + "optional": true + }, + { + "name": "seq", + "type": 18, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 193, + "optional": true + }, + { + "name": "surfaceOp", + "type": 194, + "optional": false + }, + { + "name": "time", + "type": 18, + "optional": false + }, + { + "name": "type", + "type": 197, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 32, + 35, + 37, + 39, + 41, + 43, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 61, + 62, + 63, + 64, + 65, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 109, + 111, + 114, + 115, + 116, + 117, + 118, + 120, + 121, + 122, + 123, + 125, + 126, + 127, + 128, + 129, + 131, + 132, + 133, + 135, + 136, + 144, + 146, + 147, + 149, + 151, + 155, + 157, + 165, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 183, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 108, + "optional": false + }, + { + "name": "revision", + "type": 18, + "optional": false + }, + { + "name": "round", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 110, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 112, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 113, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 119, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 124, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 130, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 25, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 137, + "optional": false + }, + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 143, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 138 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 139, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 140, + 141, + 142 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 145, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 152, + "optional": false + }, + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 154, + "optional": false + }, + { + "name": "update", + "type": 25, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 153 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 156, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 158, + "optional": false + }, + { + "name": "references", + "type": 159, + "optional": false + }, + { + "name": "version", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 160 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 18, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 161, + "optional": false + }, + { + "name": "compacted", + "type": 163, + "optional": false + }, + { + "name": "inputIndex", + "type": 18, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 18, + "optional": false + }, + { + "name": "omittedMessages", + "type": 18, + "optional": false + }, + { + "name": "originalMessages", + "type": 18, + "optional": false + }, + { + "name": "retainedMessages", + "type": 18, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 162 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 168 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 182, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 184, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 18 + }, + { + "kind": "union", + "types": [ + 195, + 196 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 18, + "optional": false + }, + { + "name": "op", + "type": 141, + "optional": false + }, + { + "name": "startSeq", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user/message" + } + ] + } + } + ], + "types": [] +} diff --git a/docs/persistence-changes/2026-09-16-session-format-v4.zh.md b/docs/persistence-changes/2026-09-16-session-format-v4.zh.md new file mode 100644 index 0000000000..16a1793797 --- /dev/null +++ b/docs/persistence-changes/2026-09-16-session-format-v4.zh.md @@ -0,0 +1,120 @@ +--- +description: "记录持久化类型更改及其兼容性确认。" +kind: persistence-change +--- + +# 2026-09-16-session-format-v4 + +[English](2026-09-16-session-format-v4.md) | 中文 + +## 概述 + +将 已定稿 V4 写入方声明的 SessionHeader.version 从 3 推进到 4,记录一等 tool 角色结果与生产者拥有的 source,并向 turn/end.reason 添加 forked 变体。 添加 developer 角色的 Session 变更,工具添加仅记录名称并绑定历史请求头,另含工具移除和延迟加载模式标记。 + +## 目录 + +- [声明](#declaration) +- [兼容性](#compatibility) +- [验证](#verification) +- [开发备注](#dev-note) + + +## 声明 + +```yaml persistence-change +schemaVersion: 1 +id: 2026-09-16-session-format-v4 +baseline: false +changes: + - root: "SessionHeader" + previous: "2026-09-11-initial" + after: "1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445" + decision: version-bump + - root: "event:agent/inbox/spliced" + previous: "2026-09-14-image-offload" + after: "1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c" + decision: version-bump + - root: "event:assistant/attempt" + previous: "2026-09-14-image-offload" + after: "15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4" + decision: version-bump + - root: "event:assistant/message" + previous: "2026-09-14-image-offload" + after: "1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625" + decision: version-bump + - root: "event:compaction/summary" + previous: "2026-09-14-image-offload" + after: "e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602" + decision: version-bump + - root: "event:developer/message" + previous: null + after: "eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80" + decision: version-bump + - root: "event:request/header" + previous: "2026-09-11-initial" + after: "4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41" + decision: version-bump + - root: "event:session/title-llm-request" + previous: "2026-09-14-image-offload" + after: "fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d" + decision: version-bump + - root: "event:system/message" + previous: "2026-09-14-image-offload" + after: "69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1" + decision: version-bump + - root: "event:team/message/queued" + previous: "2026-09-14-image-offload" + after: "21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d" + decision: version-bump + - root: "event:tool/ptc-dispatch" + previous: "2026-09-14-image-offload" + after: "100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163" + decision: version-bump + - root: "event:tool/result" + previous: "2026-09-14-image-offload" + after: "7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397" + decision: version-bump + - root: "event:turn/end" + previous: "2026-09-14-image-offload" + after: "0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce" + decision: version-bump + - root: "event:user/message" + previous: "2026-09-14-image-offload" + after: "3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761" + decision: version-bump +``` + + +## 兼容性 + +工具角色声明会改变十个事件根,因为 inbox 条目、消息事件、compaction 摘要、标题请求、团队消息和 PTC dispatch 嵌入了共享的 `Message` 或 `ContentBlock` 声明。从联合中移除 `tool-result` 并按角色细化消息,会改变这些可达 schema,并非新增十套独立事件协议。`turn/end` 的变更单独记录 forked reason;`SessionHeader` 记录版本递增。 + +[原生 V4 校验决策](../../.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.zh.md) 负责说明这些当前字段所需的读取接纳规则。 + +V3-to-V4 迁移将已发布的 user 角色工具结果提升为 tool 角色消息,包含必需的 toolCallId 和可选的 isError。工具结果包装不再属于内容块联合。迁移保留每个已接纳源事件和继承切分点,并根据同一持久化根目录中保留的直属子 Session 日志追加缺失的父级 subagent/catalog 记录。历史正文恢复要求显式提供子日志证据集合;没有可供补全的子日志时也须传入空集合。子日志的 descriptor 缺失、多条或版本未知时,跳过该子项的补全;身份、时间戳或模式冲突会拒绝迁移且不发布后继。已有 catalog 事实保持不变。历史读取打开在内存中准备结果。写入打开在重新校验子项成员与修订后,将当前后继发布到未修改的前代文件旁。Delivery generation 校验防止历史确认成为有效的 V4 水位。V3 读取方拒绝更新的 generation。已定稿迁移向 turn/end.reason 添加 forked。精确切点的 fork 在继承标记之后追加子会话自有的错误结果和结束事件。V4 接纳经过校验、使用确定性分支 ID 和文案的未启动 fork 结果;已发布的 V0–V3 校验器和已记录的前驱代际保持不变。 + +`request/header` schema 还将退役的 `system` 键记录为禁止字段。这项声明记录已有的原生读取拒绝规则,不改变存储数据或提示词重建;以后允许该字段携带值时,必须提升格式版本,而不能归类为普通可选字段添加。 + +生产者拥有的 source 通过 [V3→V4 迁移](../../packages/session/session-format-v3-to-v4/README.zh.md#v3-to-v4-specification)替代已发布的 plugin wrapper。冻结的重命名表和冲突规则保留 source 字段与事件坐标;未知生产者归属保留每个自有 JSON 属性。原生读取和写入打开在公开 Session 之前校验 source 字段。已有 V4 文件不会重新运行迁入边。 + +核心拥有的 user source 属性记录归属保留策略;tmux-context 将位置归属标记为符合条件,同时保留生产者内部的去重。Auto Review 和压缩摘要器使用仅供请求使用的 user 输入,移除其活动 source 注册,同时保留历史迁移支持。这些输入不能写为持久化 Session 消息。目录 formatVersion 2 保存策略元数据,不改变 Session 版本,也不重写冻结的 schema 记录。System、model 和 tool source 保持严格的语义规则。 + +Developer 事件保留原始角色,并要求处于打开的 step。每个添加块存储 toolName;developer/message.headerSeq 指向更早且已知的 request/header,其中必须恰好包含一个完整同名 ToolSchema。同一事件的所有添加共用该历史请求头版本,仅移除或其他 developer 消息省略 headerSeq。原生与 Session 接纳拒绝缺失、前向、非请求头、未知请求头、歧义、不完整定义及已退役内嵌定义形式,不解释未知且可忽略的记录,也不丢弃无关 JSON 元数据。同名替换、重启、fork、surface 替换和压缩保留历史模式身份,不查询最新请求头或注册表。通用 sourceEventSeqs 保持独立。Developer source 使用与 user source 相同的已记录归属保留策略。可选的 deferLoading 标记独立于添加历史。已提供的 profile 不发出 developer 记录;提供方序列化、自动发出及 UI 支持仍未启用。 + +PTC 生产者写入 `source.kind: 'ptc-mode'`。V3→V4 迁入边保留 `tools-code-mode` 和 `tools-ptc` 作为历史 plugin 查找键,并将二者映射到该当前 kind。source 策略保留 `ptc-mode`,不允许将其声明为仅用于归属。 + + +## 验证 + +精确切点 fork 集成后,聚焦的 Session、agent-loop、Session Controller、V4、chat-view 和 compaction 测试共 63 个文件、1,523 个测试通过。V4 fork 测试确认编码、解码和恢复保留原始 ID 与文本,拒绝格式错误的结果,并验证嵌套继承切点。工具角色迁移测试和 SDK 快照刷新也在原始变更中通过;构建后的 Python runtime sdk-snapshot 场景通过,定向 pi-ai 与 auto-review 覆盖率检查通过 351 个测试,三个受影响模块覆盖率均为 100%。 + +生成的请求头保留字段回归测试以及已有的退役语法和 Session surface 测试共通过三个文件中的 65 项测试。生成字段保留可选的 `never`;允许可选字符串会产生必须提升版本的诊断,而原生读取方仍拒绝该退役键。 + +Producer-source 与 request-input 检查共通过 12 个文件中的 447 项测试,覆盖 provider 等价性、仅供请求使用的输入的类型拒绝、user 归属保留、source 迁移及原生 source 准入。与 tool-role 父层的生成目录相比,有四个 root 发生变化,447 个类型指纹保持不变。 + +聚焦的 Session、V4 和 request-input 测试共 38 个文件、884 项通过,完整 V3-to-V4 包与 Session surface 的语句、分支、函数及行覆盖率均为 100%。覆盖历史同名模式绑定、复合添加/移除、畸形引用与定义、未知请求头拒绝、未知记录不透明性、元数据保留、fork、替换、压缩引用,以及不重写 generation 的原生 plain/zstd 读写接纳。 + + +## 开发备注 + +无。 diff --git a/docs/persistence-changes/README.i18n.yaml b/docs/persistence-changes/README.i18n.yaml index 27f2099f31..830e77b05e 100644 --- a/docs/persistence-changes/README.i18n.yaml +++ b/docs/persistence-changes/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/persistence-changes/README.md -README.md: 7eb46efe69e139c294ad76e1b584e2d7384151b5 -README.zh.md: d91cfff9e5010bfff92b905ce0f075e7e419eb52 +README.md: 3fd95e48548fdb9c1d04330c2925096d072850d1 +README.zh.md: f4ab3b3d22b1aa2f7f5923e84fd4effc339874db diff --git a/docs/persistence-changes/README.md b/docs/persistence-changes/README.md index 7eb46efe69..3fd95e4854 100644 --- a/docs/persistence-changes/README.md +++ b/docs/persistence-changes/README.md @@ -37,6 +37,10 @@ Each dated record has four sibling files: | `YYYY-MM-DD-slug.i18n.yaml` | Generated bilingual consistency record | | `YYYY-MM-DD-slug.schema.json` | Generated complete after schemas for the affected roots that remain present | +`finalized/vN.json` records the complete root classifications/digests of an accepted compatibility baseline and semantic hashes of its accepted records. The [finalization record](../session-format-status.md#finalization-record) requires its checkpoint. Current V4 schemas may evolve compatibly; the checkpoint protects accepted machine declarations and after schemas even after the writer advances, while excluding prose, aliases, and source locations from record hashes. + +A maintainer captures an agreed format with [`createPersistenceFinalizationCheckpoint`](../../scripts/persistence-finalization.ts), writes a new version-named checkpoint without replacing an earlier one, and advances the paired `latestFinalizedVersion`. The helper requires current schemas to match complete acknowledged history. Run the ordinary verifier before committing. + The [record template](../../.agents/skills/dsh-doc/templates/persistence-change.md) defines the authored format. Record creation accepts a bilingual prose input and generates the machine declaration, snapshots, catalog pair, and consistency records. The verifier reads the machine declaration once from the English file and checks the Chinese declaration for equality. A declaration names each affected root, its predecessor record, its after digest, and its compatibility decision. A new root has no predecessor; a deletion has no after schema and retains an explicit tombstone. @@ -49,19 +53,26 @@ Every detected structural change requires an acknowledgement. Record creation an | Add an optional event-body property, including its complete subtree | `same-version` | | Make a required event-body property optional | `same-version` | | Add an ordinary event type | `same-version` | +| Add an explicitly qualified attribution kind to a user/developer source slot whose before and after schemas carry the same supported policy | `same-version` | | Make an optional property required, add a required property, change an existing type, or remove/rename a property or event | `version-bump` | | Change the Session header or event envelope | `version-bump` | +A finalized checkpoint protects the accepted baseline without replacing these compatibility rules. At V4, optional additions, ordinary events, and qualified attribution additions can receive new same-version records. Breaking differences require a higher writer version and an acknowledgement containing its own header increase. The accepted V4 record cannot be updated to reuse its original 3→4 transition. + +The extractor accepts an explicit `@persistenceSource` binding for a core-owned source property on a literal user or developer role; it does not infer a binding from an unannotated type. A producer qualifies its `MessageSourceMap` entry with `@persistenceAttribution`. Qualification promises that an unknown kind and its JSON metadata survive reading without the producer, and that the kind imposes no validation, replay, or authority requirement. A producer may inspect its own kind to resume duplicate suppression; other readers must preserve and derive the recorded messages without that projection. The recorded schema retains the binding, policy version, literal `kind` discriminator, preservation promise, and qualified kind set. Inventory format 2 stores those promises; extraction without a bound policy retains format 1. Session format versions are independent. Both compared snapshots must carry compatible policy state. Existing kind groups still receive ordinary structural comparison; removals, unmarked additions, policy changes, and unrelated breaking changes remain strict. Multiple context-form alternatives with the same wire kind form one group. + A same-version explanation states why old records can omit the addition and why older readers can ignore it without changing replay. For required-to-optional changes, it explains how readers handle an absent value. The checker validates the type classification; reviewers assess the explanation. A version-bump record includes the increasing header version in the same transition and follows the [Session-format procedure](../cookbook/adding-a-session-format-version.md). +When a reader rejects a JSON property by name, declare the property as optional `never` and mark it with argument-free `@persistenceReserved`. The extractor retains the forbidden field, so allowing a JSON value later requires an existing-field type change. Required or JSON-valued properties cannot carry this marker. Unmarked optional `never` and `undefined` properties retain their existing omission behavior. + ## History and limitations One baseline records the complete initial inventory. Later records use their predecessor's after schema as the before schema. The verifier rejects missing predecessors, cycles, duplicate successors for one root, digest mismatches, and current roots that disagree with their latest records. Independent roots can advance independently. Two changes to the same predecessor require a single ordered history after integration. -Accepted records describe historical transitions; preserve their machine declarations and schema snapshots when adding a successor. An unaccepted terminal record can be refreshed explicitly; the command rejects baselines and records with dependants. The tree cannot establish review acceptance. Verification proves consistency within the tree, not that history was never rewritten. No Git ref, remote service, or released checkout supplies the baseline. +Accepted records describe historical transitions; preserve their machine declarations and schema snapshots when adding a successor. An unaccepted terminal record can be refreshed explicitly; the command rejects baselines, records with dependants, and checkpoint-locked records before producing artifacts. Verification checks retained checkpoint hashes; it does not prove that the checkpoints and their authority record were never edited together. No Git ref, remote service, or released checkout supplies the baseline. -Digests describe declared persistence types, not runtime validation or behavior. Comments, source locations, alias names, and harmless declaration reordering do not affect them. Object fields, union alternatives, intersection operands, and index signatures can be reordered when their resolved types stay the same; tuple positions and numeric enum values remain significant. Catalog text and source locations may still change, so regenerate stale artifacts without adding an acknowledgement for an unchanged digest. Opaque types such as `unknown` expose no hidden structure to compare. Behavior-only changes and structures hidden inside opaque values are outside this mechanism's scope. The [decision](../../.agents/notes/implemented/process/2026-09-11-persistence-type-history.md) records these trade-offs. +Digests describe declared persistence types, not runtime validation or behavior. Ordinary comments, source locations, alias names, and harmless declaration reordering do not affect them. Compatibility annotations are recorded policy data and do affect digests. Unannotated version-1 snapshots retain their original normalization, fingerprints, and strict classification; policy-bearing graphs use a separate fingerprint domain. Object fields, union alternatives, intersection operands, and index signatures can be reordered when their resolved types stay the same; tuple positions and numeric enum values remain significant. Catalog text and source locations may still change, so regenerate stale artifacts without adding an acknowledgement for an unchanged digest. Opaque types such as `unknown` expose no hidden structure to compare. Behavior-only changes and structures hidden inside opaque values are outside this mechanism's scope. The [decision](../../.agents/notes/implemented/process/2026-09-11-persistence-type-history.md) records these trade-offs. ## Dev Note diff --git a/docs/persistence-changes/README.zh.md b/docs/persistence-changes/README.zh.md index d91cfff9e5..f4ab3b3d22 100644 --- a/docs/persistence-changes/README.zh.md +++ b/docs/persistence-changes/README.zh.md @@ -37,6 +37,10 @@ description: "审阅和维护已记录的会话持久化类型变更、对应 sc | `YYYY-MM-DD-slug.i18n.yaml` | 生成的双语一致性记录 | | `YYYY-MM-DD-slug.schema.json` | 生成的完整变更后 schema,覆盖受影响且仍然存在的根 | +`finalized/vN.json` 记录已接受兼容性基线的完整根分类/摘要,以及对应已接受记录的语义哈希。[定稿记录](../session-format-status.zh.md#finalization-record)要求检查点存在。当前 V4 schema 可以兼容演进;即使写入器已推进,检查点仍保护已接受的机器声明和变更后 schema,而记录哈希不包含说明文字、别名和源码位置。 + +维护者通过 [`createPersistenceFinalizationCheckpoint`](../../scripts/persistence-finalization.ts) 捕获已确认格式,写入按版本命名的新检查点而不替换旧文件,并推进双语 `latestFinalizedVersion`。该函数要求当前 schema 与完整确认历史一致。提交前运行常规验证器。 + [记录模板](../../.agents/skills/dsh-doc/templates/persistence-change.md)定义人工编写的格式。创建记录时可以提供双语说明输入,由命令生成机器声明、快照、目录对和一致性记录。验证器从英文文件读取一次机器声明,并检查中文声明是否相同。声明列出每个受影响的根、其前驱记录、变更后摘要和兼容性决策。新根没有前驱;删除操作没有变更后 schema,并保留显式删除标记。 @@ -49,19 +53,26 @@ description: "审阅和维护已记录的会话持久化类型变更、对应 sc | 添加可选事件体属性,包括其完整子树 | `same-version` | | 将必选事件体属性改为可选 | `same-version` | | 添加普通事件类型 | `same-version` | +| 在前后 schema 均带有相同受支持策略的 user/developer 消息源字段中,添加显式声明为归属信息的 kind | `same-version` | | 将可选属性改为必选、添加必选属性、更改已有类型,或删除/重命名属性或事件 | `version-bump` | | 更改会话头或事件封装 | `version-bump` | +定稿检查点保护已接受基线,不替换这些兼容性规则。在 V4 中,可选新增、普通事件及符合条件的归属 kind 新增可以使用新的同版本记录。破坏性差异要求更高的写入器版本,以及包含自身头版本递增的确认记录。不能更新已接受 V4 记录以复用其原有 3→4 转换。 + +提取器接受核心拥有的 source 属性上针对 user 或 developer 字面量角色的显式 `@persistenceSource` 绑定,不会从未标记类型中推断绑定。生产者用 `@persistenceAttribution` 标记其 `MessageSourceMap` 成员。该标记承诺:读取器无需生产者即可保留未知 kind 及其 JSON 元数据,且该 kind 不引入校验、回放或权限要求。生产者可以检查自身 kind 来恢复去重状态;其他读取器必须无需该投影也能保留并派生已记录的消息。记录的 schema 保存绑定、策略版本、字面量 `kind` 判别字段、保留承诺及符合条件的 kind 集合。Inventory format 2 保存这些承诺;没有绑定策略的提取仍使用 format 1。Session 格式版本独立于此。比较双方的快照必须带有兼容的策略状态。已有 kind 分组仍进行常规结构比较;删除、未标记的添加、策略更改及无关破坏性变更继续采用严格规则。同一 wire kind 的多个上下文形式分支归为一组。 + 同版本说明须解释旧记录为何可以缺少新增内容,以及旧读取器为何可以忽略它而不改变回放。对于必选改可选的变更,说明须解释读取器如何处理缺失值。检查器验证类型分类;审阅者判断说明是否成立。升版本记录在同一转换中包含递增的头部版本,并遵循[会话格式流程](../cookbook/adding-a-session-format-version.zh.md)。 +当读取器按属性名拒绝 JSON 字段时,将该属性声明为可选 `never`,并添加无参数的 `@persistenceReserved` 标记。提取器保留这一禁止字段,因此后续允许 JSON 值属于已有字段类型变更。必选属性或允许 JSON 值的属性不能携带该标记。未标记的可选 `never` 和 `undefined` 属性保留现有省略行为。 + ## 历史与限制 一条基线记录完整的初始清单。后续记录使用前驱的变更后 schema 作为变更前 schema。验证器拒绝缺失前驱、环、同一根的重复后继、摘要不匹配,以及当前根与最新记录不一致的情况。独立的根可以独立演进。同一前驱上的两个变更在集成后需要形成一条有序历史。 -已接受记录描述历史转换;添加后继时须保留其机器声明和 schema 快照。尚未接受的末端记录可以显式刷新;命令拒绝基线及被依赖的记录。目录本身无法证明审阅接受状态。验证证明目录内的一致性,不证明历史从未被改写。基线不依赖 Git 引用、远端服务或已发布版本的检出目录。 +已接受记录描述历史转换;添加后继时须保留其机器声明和 schema 快照。尚未接受的末端记录可以显式刷新;命令在生成产物前拒绝基线、被依赖的记录和被检查点锁定的记录。验证检查所保留检查点的哈希,但不证明检查点及其真源记录从未被一起修改。基线不依赖 Git 引用、远端服务或已发布版本的检出目录。 -摘要描述声明的持久化类型,不描述运行时验证或行为。注释、源码位置、别名名称和无语义变化的声明重排不影响摘要。对象字段、联合类型分支、交叉类型操作数和索引签名可以在解析类型不变时重排;元组位置和数字枚举值仍然影响摘要。目录文本和源码位置仍可能变化,因此应重新生成陈旧产物,无需为未变的摘要添加确认记录。`unknown` 等不透明类型不提供可比较的内部结构。纯行为变更以及不透明值中隐藏的结构不在本机制范围内。[决策记录](../../.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md)说明这些取舍。 +摘要描述声明的持久化类型,不描述运行时验证或行为。普通注释、源码位置、别名名称和无语义变化的声明重排不影响摘要。兼容性标记是记录的策略数据,会影响摘要。不带标记的版本 1 快照保留原有规范化、指纹和严格分类;包含策略的图使用独立的指纹域。对象字段、联合类型分支、交叉类型操作数和索引签名可以在解析类型不变时重排;元组位置和数字枚举值仍然影响摘要。目录文本和源码位置仍可能变化,因此应重新生成陈旧产物,无需为未变的摘要添加确认记录。`unknown` 等不透明类型不提供可比较的内部结构。纯行为变更以及不透明值中隐藏的结构不在本机制范围内。[决策记录](../../.agents/notes/implemented/process/2026-09-11-persistence-type-history.zh.md)说明这些取舍。 ## 开发备注 diff --git a/docs/persistence-changes/finalized/v4.json b/docs/persistence-changes/finalized/v4.json new file mode 100644 index 0000000000..d9490b84df --- /dev/null +++ b/docs/persistence-changes/finalized/v4.json @@ -0,0 +1,379 @@ +{ + "schemaVersion": 1, + "sessionFormatVersion": 4, + "roots": { + "JsonlHeaderLine": { + "kind": "header", + "digest": "18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f" + }, + "SessionEventEnvelope": { + "kind": "envelope", + "digest": "5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc" + }, + "SessionHeader": { + "kind": "header", + "digest": "1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445" + }, + "event:agent-preset/selected": { + "kind": "event", + "digest": "a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b", + "event": "agent-preset/selected", + "surface": false + }, + "event:agent/inbox/spliced": { + "kind": "event", + "digest": "1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c", + "event": "agent/inbox/spliced", + "surface": false + }, + "event:approval/asked": { + "kind": "event", + "digest": "3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1", + "event": "approval/asked", + "surface": false + }, + "event:approval/decided": { + "kind": "event", + "digest": "bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3", + "event": "approval/decided", + "surface": false + }, + "event:approval/policy": { + "kind": "event", + "digest": "26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78", + "event": "approval/policy", + "surface": false + }, + "event:assistant/attempt": { + "kind": "event", + "digest": "15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4", + "event": "assistant/attempt", + "surface": false + }, + "event:assistant/message": { + "kind": "event", + "digest": "1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625", + "event": "assistant/message", + "surface": true + }, + "event:command/done": { + "kind": "event", + "digest": "15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff", + "event": "command/done", + "surface": false + }, + "event:command/run": { + "kind": "event", + "digest": "37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006", + "event": "command/run", + "surface": false + }, + "event:compaction/end": { + "kind": "event", + "digest": "b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d", + "event": "compaction/end", + "surface": false + }, + "event:compaction/prune": { + "kind": "event", + "digest": "7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04", + "event": "compaction/prune", + "surface": false + }, + "event:compaction/start": { + "kind": "event", + "digest": "db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965", + "event": "compaction/start", + "surface": false + }, + "event:compaction/summary": { + "kind": "event", + "digest": "e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602", + "event": "compaction/summary", + "surface": false + }, + "event:deliverables/presented": { + "kind": "event", + "digest": "13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176", + "event": "deliverables/presented", + "surface": false + }, + "event:developer/message": { + "kind": "event", + "digest": "eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80", + "event": "developer/message", + "surface": true + }, + "event:feedback/message-delete": { + "kind": "event", + "digest": "3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796", + "event": "feedback/message-delete", + "surface": false + }, + "event:feedback/message-put": { + "kind": "event", + "digest": "b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf", + "event": "feedback/message-put", + "surface": false + }, + "event:feedback/record": { + "kind": "event", + "digest": "b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8", + "event": "feedback/record", + "surface": false + }, + "event:goal/change": { + "kind": "event", + "digest": "763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d", + "event": "goal/change", + "surface": false + }, + "event:hook/invoked": { + "kind": "event", + "digest": "8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0", + "event": "hook/invoked", + "surface": false + }, + "event:hook/result": { + "kind": "event", + "digest": "e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4", + "event": "hook/result", + "surface": false + }, + "event:image/offload": { + "kind": "event", + "digest": "b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e", + "event": "image/offload", + "surface": false + }, + "event:llm/retry": { + "kind": "event", + "digest": "525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336", + "event": "llm/retry", + "surface": false + }, + "event:llm/retry-started": { + "kind": "event", + "digest": "48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3", + "event": "llm/retry-started", + "surface": false + }, + "event:model/selection": { + "kind": "event", + "digest": "35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc", + "event": "model/selection", + "surface": false + }, + "event:permission/preset": { + "kind": "event", + "digest": "5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b", + "event": "permission/preset", + "surface": false + }, + "event:plan/mode": { + "kind": "event", + "digest": "a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f", + "event": "plan/mode", + "surface": false + }, + "event:request/context": { + "kind": "event", + "digest": "37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf", + "event": "request/context", + "surface": false + }, + "event:request/header": { + "kind": "event", + "digest": "4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41", + "event": "request/header", + "surface": false + }, + "event:sandbox/mode": { + "kind": "event", + "digest": "516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415", + "event": "sandbox/mode", + "surface": false + }, + "event:schedule/change": { + "kind": "event", + "digest": "2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42", + "event": "schedule/change", + "surface": false + }, + "event:session-log-deepseek/delivery-accepted": { + "kind": "event", + "digest": "d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9", + "event": "session-log-deepseek/delivery-accepted", + "surface": false + }, + "event:session/end-seed": { + "kind": "event", + "digest": "5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e", + "event": "session/end-seed", + "surface": false + }, + "event:session/title": { + "kind": "event", + "digest": "1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5", + "event": "session/title", + "surface": false + }, + "event:session/title-llm-request": { + "kind": "event", + "digest": "fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d", + "event": "session/title-llm-request", + "surface": false + }, + "event:step/end": { + "kind": "event", + "digest": "e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05", + "event": "step/end", + "surface": false + }, + "event:step/start": { + "kind": "event", + "digest": "4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986", + "event": "step/start", + "surface": false + }, + "event:subagent/catalog": { + "kind": "event", + "digest": "ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871", + "event": "subagent/catalog", + "surface": false + }, + "event:subagent/descriptor": { + "kind": "event", + "digest": "b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5", + "event": "subagent/descriptor", + "surface": false + }, + "event:subagent/model-selection-policy": { + "kind": "event", + "digest": "a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc", + "event": "subagent/model-selection-policy", + "surface": false + }, + "event:system/message": { + "kind": "event", + "digest": "69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1", + "event": "system/message", + "surface": true + }, + "event:team/member": { + "kind": "event", + "digest": "4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc", + "event": "team/member", + "surface": false + }, + "event:team/message/delivered": { + "kind": "event", + "digest": "48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb", + "event": "team/message/delivered", + "surface": false + }, + "event:team/message/queued": { + "kind": "event", + "digest": "21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d", + "event": "team/message/queued", + "surface": false + }, + "event:team/task": { + "kind": "event", + "digest": "d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a", + "event": "team/task", + "surface": false + }, + "event:todo/write": { + "kind": "event", + "digest": "b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26", + "event": "todo/write", + "surface": false + }, + "event:tool-workflow/agent-end": { + "kind": "event", + "digest": "babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7", + "event": "tool-workflow/agent-end", + "surface": false + }, + "event:tool-workflow/agent-start": { + "kind": "event", + "digest": "5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627", + "event": "tool-workflow/agent-start", + "surface": false + }, + "event:tool-workflow/run-end": { + "kind": "event", + "digest": "42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f", + "event": "tool-workflow/run-end", + "surface": false + }, + "event:tool-workflow/run-start": { + "kind": "event", + "digest": "c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058", + "event": "tool-workflow/run-start", + "surface": false + }, + "event:tool/call": { + "kind": "event", + "digest": "3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48", + "event": "tool/call", + "surface": false + }, + "event:tool/ptc-dispatch": { + "kind": "event", + "digest": "100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163", + "event": "tool/ptc-dispatch", + "surface": false + }, + "event:tool/ptc-dispatch-start": { + "kind": "event", + "digest": "ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93", + "event": "tool/ptc-dispatch-start", + "surface": false + }, + "event:tool/result": { + "kind": "event", + "digest": "7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397", + "event": "tool/result", + "surface": true + }, + "event:turn/end": { + "kind": "event", + "digest": "0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce", + "event": "turn/end", + "surface": false + }, + "event:turn/start": { + "kind": "event", + "digest": "aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8", + "event": "turn/start", + "surface": false + }, + "event:user/message": { + "kind": "event", + "digest": "3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761", + "event": "user/message", + "surface": true + }, + "event:web/deepseek-search-llm-request": { + "kind": "event", + "digest": "cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331", + "event": "web/deepseek-search-llm-request", + "surface": false + }, + "event:workspace/changes": { + "kind": "event", + "digest": "e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72", + "event": "workspace/changes", + "surface": false + } + }, + "acceptedRecords": { + "2026-09-11-initial": "1257b73faa71fda3504b42af8ef7fa6a8c608a1aafe4fc77f21b8cd1c30e0ec1", + "2026-09-12-auto-review-error-metadata": "a98f6eb5d28618a355a358bddf7b278a25ab8aa08288c85e32c2031d7994b865", + "2026-09-14-image-offload": "ec2ac7c3e20842e33870307384200b893a3ec0b0028882858abb0ac9dfc002c6", + "2026-09-14-workspace-changes-event": "b5455973864a92f227f4af0c8eae2182dc33a20d22d2121083652aa0e61af83d", + "2026-09-16-session-format-v4": "0d854cc665bea188f82b6b8d2298a7e484fd138dfdf1d1e974b8be2c9f15c6ac" + } +} diff --git a/docs/persistence-changes/historical-formats/README.i18n.yaml b/docs/persistence-changes/historical-formats/README.i18n.yaml index b60b927322..15481ef915 100644 --- a/docs/persistence-changes/historical-formats/README.i18n.yaml +++ b/docs/persistence-changes/historical-formats/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/persistence-changes/historical-formats/README.md -README.md: fda6ac3b4fc3e52ef215dc0a2fca00576cd4ef0c -README.zh.md: 792f47e532d6ebfdbb745c1bc2703c7b5f4fcc17 +README.md: 9bcfaa1246a03446d4d4fc95dd19f9ca60196301 +README.zh.md: 1f17367beb484feaeb289a42b3e5de50d3139be5 diff --git a/docs/persistence-changes/historical-formats/README.md b/docs/persistence-changes/historical-formats/README.md index fda6ac3b4f..9bcfaa1246 100644 --- a/docs/persistence-changes/historical-formats/README.md +++ b/docs/persistence-changes/historical-formats/README.md @@ -31,7 +31,8 @@ The index is generated from validated snapshots and the current writer constant. | 0 | `dsh-v0.1.2-rc.1` | [V0](v0.md) | [JSON](v0.schema.json) | 54 / 415 | | 1 | PR #3349 | [V1](v1.md) | [JSON](v1.schema.json) | 54 / 415 | | 2 | `dsh-v0.1.3-alpha.2` | [V2](v2.md) | [JSON](v2.schema.json) | 56 / 435 | -| 3 | Current checkout | [Current catalog](../../persistence-catalog.md) | [JSON](../../persistence-schema.json) | 61 / 470 | +| 3 | PR #4320 | [V3](v3.md) | [JSON](v3.schema.json) | 60 / 467 | +| 4 | Current checkout | [Current catalog](../../persistence-catalog.md) | [JSON](../../persistence-schema.json) | 62 / 583 | @@ -40,7 +41,7 @@ The index is generated from validated snapshots and the current writer constant. Each `vN.md` / `vN.zh.md` pair has `kind: persistence-format`, an identical `yaml persistence-format` declaration binding every root key to its captured digest, a pairing sidecar, and a complete `vN.schema.json`. The [template](../../../.agents/skills/dsh-doc/templates/persistence-format.md) defines these records. Roots cover the logical Session header, physical JSONL header, event envelope, and all first-party events at the selected checkpoint; each root includes every reachable declared type. Packed physical body records have separate codec owners linked from each page. -V0 and V2 use the latest matching tags in the [captured prerelease archive](../releases/README.md). V1 uses an intermediate source tree identified in its reference because the captured tags contain no V1 writer. Historical sources retain file paths without line numbers. Snapshots preserve historical optional fields and opaque values; they do not substitute current types into older formats. Historical identifiers remain intact only in schema JSON and the verified generated schema regions; authored prose follows current terminology rules. +V0 and V2 use the latest matching tags in the [captured prerelease archive](../releases/README.md). V1 uses an intermediate source tree identified in its reference because the captured tags contain no V1 writer. V3 captures the verified inventory before the V4 writer change in PR #4320. Historical sources retain file paths without line numbers. Snapshots preserve historical optional fields and opaque values; they do not substitute current types into older formats. Historical identifiers remain intact only in schema JSON and the verified generated schema regions; authored prose follows current terminology rules. These references describe selected schemas, not historical application replay or migration safety. Same-version event additions and optional payload changes can produce other valid inventories. The prerelease archive retains tag-by-tag differences; [change records](../README.md) retain current compatibility acknowledgements. Neither history is replaced by these format snapshots. diff --git a/docs/persistence-changes/historical-formats/README.zh.md b/docs/persistence-changes/historical-formats/README.zh.md index 792f47e532..1f17367beb 100644 --- a/docs/persistence-changes/historical-formats/README.zh.md +++ b/docs/persistence-changes/historical-formats/README.zh.md @@ -31,7 +31,8 @@ description: "查找从 V0 到工作区写入器版本的每个 Session 格式 | 0 | `dsh-v0.1.2-rc.1` | [V0](v0.zh.md) | [JSON](v0.schema.json) | 54 / 415 | | 1 | PR #3349 | [V1](v1.zh.md) | [JSON](v1.schema.json) | 54 / 415 | | 2 | `dsh-v0.1.3-alpha.2` | [V2](v2.zh.md) | [JSON](v2.schema.json) | 56 / 435 | -| 3 | 当前工作树 | [当前目录](../../persistence-catalog.zh.md) | [JSON](../../persistence-schema.json) | 61 / 470 | +| 3 | PR #4320 | [V3](v3.zh.md) | [JSON](v3.schema.json) | 60 / 467 | +| 4 | 当前工作树 | [当前目录](../../persistence-catalog.zh.md) | [JSON](../../persistence-schema.json) | 62 / 583 | @@ -40,7 +41,7 @@ description: "查找从 V0 到工作区写入器版本的每个 Session 格式 每组 `vN.md` / `vN.zh.md` 文档包含 `kind: persistence-format`、将每个根类型键绑定到已记录摘要的相同 `yaml persistence-format` 声明、配对记录及完整的 `vN.schema.json`。[模板](../../../.agents/skills/dsh-doc/templates/persistence-format.md)定义这些记录。根类型覆盖所选检查点的逻辑 Session header、物理 JSONL header、事件信封与所有第一方事件;每个根包含所有可达的声明类型。打包的物理 body 记录由每页链接的独立 codec 负责。 -V0 与 V2 使用[已收录预发布归档](../releases/README.zh.md)中最后一个对应 tag。由于收录的 tag 没有 V1 写入器,V1 使用其参考文档中标识的中间源码树。历史来源保留文件路径,不包含行号。快照保留历史可选字段与不透明值,不会将当前类型替换到旧格式中。历史标识符仅在 schema JSON 与已验证的生成 schema 区间中原样保留;人工说明遵循当前术语规则。 +V0 与 V2 使用[已收录预发布归档](../releases/README.zh.md)中最后一个对应 tag。由于收录的 tag 没有 V1 写入器,V1 使用其参考文档中标识的中间源码树。V3 捕获 PR #4320 中 V4 写入器变更前已验证的目录。历史来源保留文件路径,不包含行号。快照保留历史可选字段与不透明值,不会将当前类型替换到旧格式中。历史标识符仅在 schema JSON 与已验证的生成 schema 区间中原样保留;人工说明遵循当前术语规则。 这些参考描述选定的 schema,不表示历史应用回放结果或迁移安全性。同版本内新增事件与可选载荷变更可以产生其他有效目录。预发布归档保留逐 tag 差异;[变更记录](../README.zh.md)保留当前兼容性确认。这些格式快照不替代任何一种历史。 diff --git a/docs/persistence-changes/historical-formats/v3.i18n.yaml b/docs/persistence-changes/historical-formats/v3.i18n.yaml new file mode 100644 index 0000000000..d8b64d6969 --- /dev/null +++ b/docs/persistence-changes/historical-formats/v3.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write docs/persistence-changes/historical-formats/v3.md +v3.md: cf9d6d64b08e4e861bdb20e244e1e5d75e297323 +v3.zh.md: b49cbf23a9c66fbe2804e1f2a28ac4e5cfcd7441 diff --git a/docs/persistence-changes/historical-formats/v3.md b/docs/persistence-changes/historical-formats/v3.md new file mode 100644 index 0000000000..cf9d6d64b0 --- /dev/null +++ b/docs/persistence-changes/historical-formats/v3.md @@ -0,0 +1,5634 @@ +--- +description: "Complete Session V3 persistence types, source evidence, and physical encoding references." +kind: persistence-format +--- + +# Session V3 persistence format + +English | [中文](v3.zh.md) + +## Summary + +Inspect the V3 persistence types captured before the V4 writer change in PR #4320. System prompts use surface messages, replacement endpoints use `startSeq` / `endSeq`, and surface events have explicit placement. This snapshot preserves the complete declared inventory at that V3 checkpoint. + +## Table of Contents + +- [Source evidence](#evidence) +- [Format characteristics](#characteristics) +- [Declaration](#declaration) +- [Complete schemas](#schema) +- [Verification and limitations](#verification) +- [Dev Note](#dev-note) + +----- + + +## Source evidence + +The source is the initial tree of PR #4320 on `release/session-log-v4`, recorded by the empty commit dated 2026-09-16 and titled `chore(session): initialize V4 release integration PR`. It contains the master tree with writer version 3, before the V4 source changes. The catalog freshness check passed and the V3 archive command captured the inventory before the writer advanced. This checkpoint is neither the final PR tree nor a new product release; the [release-status reference](../../session-format-status.md) owns publication evidence. + +The extracted declarations come from `packages/core/session/src/types.ts`, `packages/session/session-persistence-jsonl/src/format.ts`, and every first-party `SessionEventMap` merge and its reachable types. Source locations below refer to that captured tree, without line numbers. + + +## Format characteristics + +These facts describe the selected checkpoint. The generated tables below preserve the exact field types and optionality. + +- `SessionHeader.version` resolves to the literal 3. Logical and physical headers require `isSeeded`; the physical header has no `seedLength`. +- `system/message`, `user/message`, `assistant/message`, and `tool/result` require `surfaceOp`. Replacement endpoints are `startSeq` and `endSeq`; Assistant messages do not carry `sourceEventSeqs`. +- Assistant streams remain embedded in message or attempt events. System prompt text belongs to `system/message`, and PTC dispatch events use `tool/ptc-dispatch-start` and `tool/ptc-dispatch`. + +The [V3 codec](../../../packages/session/session-format-v2-to-v3/src/codec.ts) owns canonical event framing and source-event range encoding. The [V2-to-V3 specification](../../../packages/session/session-format-v2-to-v3/README.md#v2-to-v3-specification) defines historical conversion, while its [native V3 admission rules](../../../packages/session/session-format-v2-to-v3/README.md#native-v3-admission) distinguish extension handling from historical source validation. + +For a seeded V3 Session, the last `session/end-seed` event carrying `data.inherited: true` identifies the inherited cut by its sequence position. Physical `sourceEventSeqs` may use encoded ranges; the logical schemas retain expanded number arrays. + + +## Declaration + +[Schema inventory](v3.schema.json). + +```yaml persistence-format +schemaVersion: 1 +sessionFormatVersion: 3 +source: + pullRequest: 4320 +roots: + "SessionHeader": 2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03 + "JsonlHeaderLine": 18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f + "SessionEventEnvelope": 5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc + "event:agent-preset/selected": a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b + "event:agent/inbox/spliced": 646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f + "event:approval/asked": 3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1 + "event:approval/decided": bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3 + "event:approval/policy": 26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78 + "event:assistant/attempt": c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e + "event:assistant/message": 1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d + "event:command/done": 15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff + "event:command/run": 37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006 + "event:compaction/end": b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d + "event:compaction/prune": 7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04 + "event:compaction/start": db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965 + "event:compaction/summary": f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59 + "event:deliverables/presented": 13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176 + "event:feedback/message-delete": 3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796 + "event:feedback/message-put": b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf + "event:feedback/record": b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8 + "event:goal/change": 763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d + "event:hook/invoked": 8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0 + "event:hook/result": e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4 + "event:image/offload": b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e + "event:llm/retry": 525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336 + "event:llm/retry-started": 48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3 + "event:model/selection": 35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc + "event:permission/preset": 5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b + "event:plan/mode": a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f + "event:request/context": 37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf + "event:request/header": 8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489 + "event:sandbox/mode": 516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415 + "event:schedule/change": 2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42 + "event:session-log-deepseek/delivery-accepted": d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9 + "event:session/end-seed": 5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e + "event:session/title": 1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5 + "event:session/title-llm-request": e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d + "event:step/end": e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05 + "event:step/start": 4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986 + "event:subagent/catalog": ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871 + "event:subagent/descriptor": b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5 + "event:subagent/model-selection-policy": a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc + "event:system/message": 69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae + "event:team/member": 4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc + "event:team/message/delivered": 48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb + "event:team/message/queued": 443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4 + "event:team/task": d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a + "event:todo/write": b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26 + "event:tool-workflow/agent-end": babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7 + "event:tool-workflow/agent-start": 5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627 + "event:tool-workflow/run-end": 42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f + "event:tool-workflow/run-start": c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058 + "event:tool/call": 3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48 + "event:tool/ptc-dispatch": b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c + "event:tool/ptc-dispatch-start": ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93 + "event:tool/result": 29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2 + "event:turn/end": bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b + "event:turn/start": aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8 + "event:user/message": 314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578 + "event:web/deepseek-search-llm-request": cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331 +``` + + + + +## Complete schemas + +The [complete machine inventory](v3.schema.json) contains 60 roots and 467 reachable types. Digests include all referenced fields; source names and paths describe the selected historical tree. + +### Persistence type fingerprints + +| Root | Kind | SHA-256 | Resolved type | +|---|---|---|---| +| `SessionHeader` | header | `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` | [`packages/core/session/src/types.ts#SessionHeader`](#persistence-type-packagescoresessionsrctypestssessionheader) | +| `JsonlHeaderLine` | header | `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` | [`packages/session/session-persistence-jsonl/src/format.ts#HeaderLine`](#persistence-type-packagessessionsession-persistence-jsonlsrcformattsheaderline) | +| `SessionEventEnvelope` | envelope | `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` | [`SessionEventEnvelope`](#persistence-type-sessioneventenvelope) | +| `event:agent-preset/selected` | event | `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` | [`event:agent-preset/selected`](#persistence-type-eventagent-presetselected) | +| `event:agent/inbox/spliced` | event | `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` | [`event:agent/inbox/spliced`](#persistence-type-eventagentinboxspliced) | +| `event:approval/asked` | event | `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` | [`event:approval/asked`](#persistence-type-eventapprovalasked) | +| `event:approval/decided` | event | `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` | [`event:approval/decided`](#persistence-type-eventapprovaldecided) | +| `event:approval/policy` | event | `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` | [`event:approval/policy`](#persistence-type-eventapprovalpolicy) | +| `event:assistant/attempt` | event | `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` | [`event:assistant/attempt`](#persistence-type-eventassistantattempt) | +| `event:assistant/message` | event | `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` | [`event:assistant/message`](#persistence-type-eventassistantmessage) | +| `event:command/done` | event | `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` | [`event:command/done`](#persistence-type-eventcommanddone) | +| `event:command/run` | event | `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` | [`event:command/run`](#persistence-type-eventcommandrun) | +| `event:compaction/end` | event | `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` | [`event:compaction/end`](#persistence-type-eventcompactionend) | +| `event:compaction/prune` | event | `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` | [`event:compaction/prune`](#persistence-type-eventcompactionprune) | +| `event:compaction/start` | event | `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` | [`event:compaction/start`](#persistence-type-eventcompactionstart) | +| `event:compaction/summary` | event | `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` | [`event:compaction/summary`](#persistence-type-eventcompactionsummary) | +| `event:deliverables/presented` | event | `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` | [`event:deliverables/presented`](#persistence-type-eventdeliverablespresented) | +| `event:feedback/message-delete` | event | `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` | [`event:feedback/message-delete`](#persistence-type-eventfeedbackmessage-delete) | +| `event:feedback/message-put` | event | `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` | [`event:feedback/message-put`](#persistence-type-eventfeedbackmessage-put) | +| `event:feedback/record` | event | `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` | [`event:feedback/record`](#persistence-type-eventfeedbackrecord) | +| `event:goal/change` | event | `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` | [`event:goal/change`](#persistence-type-eventgoalchange) | +| `event:hook/invoked` | event | `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` | [`event:hook/invoked`](#persistence-type-eventhookinvoked) | +| `event:hook/result` | event | `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` | [`event:hook/result`](#persistence-type-eventhookresult) | +| `event:image/offload` | event | `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` | [`event:image/offload`](#persistence-type-eventimageoffload) | +| `event:llm/retry` | event | `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` | [`event:llm/retry`](#persistence-type-eventllmretry) | +| `event:llm/retry-started` | event | `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` | [`event:llm/retry-started`](#persistence-type-eventllmretry-started) | +| `event:model/selection` | event | `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` | [`event:model/selection`](#persistence-type-eventmodelselection) | +| `event:permission/preset` | event | `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` | [`event:permission/preset`](#persistence-type-eventpermissionpreset) | +| `event:plan/mode` | event | `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` | [`event:plan/mode`](#persistence-type-eventplanmode) | +| `event:request/context` | event | `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` | [`event:request/context`](#persistence-type-eventrequestcontext) | +| `event:request/header` | event | `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` | [`event:request/header`](#persistence-type-eventrequestheader) | +| `event:sandbox/mode` | event | `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` | [`event:sandbox/mode`](#persistence-type-eventsandboxmode) | +| `event:schedule/change` | event | `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` | [`event:schedule/change`](#persistence-type-eventschedulechange) | +| `event:session-log-deepseek/delivery-accepted` | event | `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` | [`event:session-log-deepseek/delivery-accepted`](#persistence-type-eventsession-log-deepseekdelivery-accepted) | +| `event:session/end-seed` | event | `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` | [`event:session/end-seed`](#persistence-type-eventsessionend-seed) | +| `event:session/title` | event | `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` | [`event:session/title`](#persistence-type-eventsessiontitle) | +| `event:session/title-llm-request` | event | `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` | [`event:session/title-llm-request`](#persistence-type-eventsessiontitle-llm-request) | +| `event:step/end` | event | `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` | [`event:step/end`](#persistence-type-eventstepend) | +| `event:step/start` | event | `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` | [`event:step/start`](#persistence-type-eventstepstart) | +| `event:subagent/catalog` | event | `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` | [`event:subagent/catalog`](#persistence-type-eventsubagentcatalog) | +| `event:subagent/descriptor` | event | `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` | [`event:subagent/descriptor`](#persistence-type-eventsubagentdescriptor) | +| `event:subagent/model-selection-policy` | event | `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` | [`event:subagent/model-selection-policy`](#persistence-type-eventsubagentmodel-selection-policy) | +| `event:system/message` | event | `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` | [`event:system/message`](#persistence-type-eventsystemmessage) | +| `event:team/member` | event | `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` | [`event:team/member`](#persistence-type-eventteammember) | +| `event:team/message/delivered` | event | `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` | [`event:team/message/delivered`](#persistence-type-eventteammessagedelivered) | +| `event:team/message/queued` | event | `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` | [`event:team/message/queued`](#persistence-type-eventteammessagequeued) | +| `event:team/task` | event | `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` | [`event:team/task`](#persistence-type-eventteamtask) | +| `event:todo/write` | event | `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` | [`event:todo/write`](#persistence-type-eventtodowrite) | +| `event:tool-workflow/agent-end` | event | `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` | [`event:tool-workflow/agent-end`](#persistence-type-eventtool-workflowagent-end) | +| `event:tool-workflow/agent-start` | event | `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` | [`event:tool-workflow/agent-start`](#persistence-type-eventtool-workflowagent-start) | +| `event:tool-workflow/run-end` | event | `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` | [`event:tool-workflow/run-end`](#persistence-type-eventtool-workflowrun-end) | +| `event:tool-workflow/run-start` | event | `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` | [`event:tool-workflow/run-start`](#persistence-type-eventtool-workflowrun-start) | +| `event:tool/call` | event | `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` | [`event:tool/call`](#persistence-type-eventtoolcall) | +| `event:tool/ptc-dispatch` | event | `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` | [`event:tool/ptc-dispatch`](#persistence-type-eventtoolptc-dispatch) | +| `event:tool/ptc-dispatch-start` | event | `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` | [`event:tool/ptc-dispatch-start`](#persistence-type-eventtoolptc-dispatch-start) | +| `event:tool/result` | event | `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` | [`event:tool/result`](#persistence-type-eventtoolresult) | +| `event:turn/end` | event | `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` | [`event:turn/end`](#persistence-type-eventturnend) | +| `event:turn/start` | event | `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` | [`event:turn/start`](#persistence-type-eventturnstart) | +| `event:user/message` | event | `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` | [`event:user/message`](#persistence-type-eventusermessage) | +| `event:web/deepseek-search-llm-request` | event | `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` | [`event:web/deepseek-search-llm-request`](#persistence-type-eventwebdeepseek-search-llm-request) | + +
+Complete resolved types + +### Resolved persistence types + +Each definition appears once. References preserve sharing and recursion; the digest beside a definition includes its complete reachable structure. Source names and locations identify its declarations but are excluded from its digest. + + + +#### `0` + +SHA-256: `93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35` + +`0` + + + +#### `1` + +SHA-256: `f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d` + +`1` + + + +#### `2` + +SHA-256: `a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80` + +`2` + + + +#### `3` + +SHA-256: `137ac60e26bcb192210d9a32a704b73b0924ed34019323defa1b787be95bd45e` + +`3` + + + +#### `"aborted"` + +SHA-256: `1e0b0b66b6f0c53fc72e52289d06b4708d776f1ca9df4c86a22bff621d403cf0` + +`"aborted"` + + + +#### `"active"` + +SHA-256: `c8e6f48878cc2a2f0dc59682280d81f407943fb503f32c64bf9ff3d9393c3eff` + +`"active"` + + + +#### `"after"` + +SHA-256: `5b232a9b9bfcc0fc6794dab7865bcf203a65785c5de5aa647a51228bff628413` + +`"after"` + + + +#### `"agent-instructions"` + +SHA-256: `fbd2c74b346a1595b376139c587fadd23e4a21acc9c0abce342975b6cfc60986` + +`"agent-instructions"` + + + +#### `"agent-message"` + +SHA-256: `82470020b5bfcb1a843e2aa05602af7d37df99e82d01f015c7c589ba054fd89d` + +`"agent-message"` + + + +#### `"agent-preset/selected"` + +SHA-256: `557e148d30b79ee48645850832b30c717d7c3b64641deb5d6133b8b4e91ee0b8` + +`"agent-preset/selected"` + + + +#### `"agent/inbox/spliced"` + +SHA-256: `829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809` + +`"agent/inbox/spliced"` + + + +#### `"allowed-once"` + +SHA-256: `811229eedcec57979dbadca7dbea832a59f8580cff30cb217fca5e2da16314bd` + +`"allowed-once"` + + + +#### `"always"` + +SHA-256: `142c37d302aa22a0a57915b5255939d3ca91c1811ca13fddcf84cf76ea00758a` + +`"always"` + + + +#### `"append"` + +SHA-256: `e438a9d4fb883b3e4a8d9fc8913aa1550ed50eb384bfbf943100a5605b537498` + +`"append"` + + + +#### `"approval/asked"` + +SHA-256: `cd186c309e2bef305705e1d324139240f5e681f4f6a957d6a25b0225f65560df` + +`"approval/asked"` + + + +#### `"approval/decided"` + +SHA-256: `378f90f9f6022a0991928a1eaf7991094ea1920fe89a9248358a1da106e1a970` + +`"approval/decided"` + + + +#### `"approval/policy"` + +SHA-256: `36d6a9a871d949ea4f3edd919d81d66aa69218bebef38899d2a1282c39420a1f` + +`"approval/policy"` + + + +#### `"ask"` + +SHA-256: `9e07693fd7cd9babe0688c22c986e4d519ae1c0e40eeea13b2dc583bed2abc86` + +`"ask"` + + + +#### `"assistant"` + +SHA-256: `95c0e88fcf0bafb2087f912ad9e2369de6ae6530cc0c4c2772c96205b57f7f60` + +`"assistant"` + + + +#### `"assistant/attempt"` + +SHA-256: `e95f957154b2b1b58692af53d4131180b6dd19e2264869f876dbaa959991494e` + +`"assistant/attempt"` + + + +#### `"assistant/message"` + +SHA-256: `6ab45ac76839722df912f3ba50f1c6b41f2d614bde11f1aabfae04117ccdc80d` + +`"assistant/message"` + + + +#### `"at"` + +SHA-256: `17aae616ef020b8b9f011ec398ec935450fb06d3e2a0722c456f63aeaf5ff728` + +`"at"` + + + +#### `"block"` + +SHA-256: `1e346446e183ee76f48d7994c97ecb302bddc682abb60b8a10ea0bb26223a69c` + +`"block"` + + + +#### `"block-end"` + +SHA-256: `eefbea819caeeea91ccb02dfafc16c68dd7f961cf9c1b2be25a2084509cf5c5a` + +`"block-end"` + + + +#### `"block-start"` + +SHA-256: `cbca49bde16b656d5b8fbe4a8a507769f7b594c6287782b809c03814941bc5e3` + +`"block-start"` + + + +#### `"blocked"` + +SHA-256: `254dce209e735f9cb6f6b7aec0354712b1611759ec02af4d35a96f2081e666f6` + +`"blocked"` + + + +#### `boolean` + +SHA-256: `aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877` + +`boolean` + + + +#### `"canceled"` + +SHA-256: `d4e4d575abeb4b72d616dc65c17ac0eaa943cc135609395044c38d5afcb10e31` + +`"canceled"` + + + +#### `"cancelled"` + +SHA-256: `2142e391b9ccb60d487afcf373ce74db98d952f69e8289eddb352a7e16e996c5` + +`"cancelled"` + + + +#### `"catalog"` + +SHA-256: `aec150797b655c5f15ebb7a501454b0c208fbaccec9ace49d7de2171fc02f47d` + +`"catalog"` + + + +#### `"change"` + +SHA-256: `f789af5ab844827eb5a4f357c0afae1eeed108c6c22d8ca1a56e586b349a7c85` + +`"change"` + + + +#### `"chunk"` + +SHA-256: `14230f9b8b5797bb7e8c621fa636531cfbde2ffba1ef5f1fd058216ff21952a0` + +`"chunk"` + + + +#### `"claude-code"` + +SHA-256: `aff60ef947c18b012644852bdd0d5bfe72065e061dd563787c76c646b4a10f6b` + +`"claude-code"` + + + +#### `"clear"` + +SHA-256: `e7e154d47d5fbc5366330fb4dade1f108c6dfe4335044d21ded14b7bf1dce084` + +`"clear"` + + + +#### `"codex"` + +SHA-256: `15495614ccfa9cbdeefb0ec2abd76406435f4c6ff3dae42acae8e09ef42025c9` + +`"codex"` + + + +#### `"command/done"` + +SHA-256: `8cdd3fdd295cee53035de16a1b23411716f75e9f994fe9510cac5d7fef605c76` + +`"command/done"` + + + +#### `"command/run"` + +SHA-256: `f1996af2602e6f62b5ab179ca5c4af00d8753938b74cc6ef102de09e99e74a7e` + +`"command/run"` + + + +#### `"compaction/end"` + +SHA-256: `1986c2664009c99155e44795676c887fa67f7c55cd2d5e6b648ff763e0ab033a` + +`"compaction/end"` + + + +#### `"compaction/prune"` + +SHA-256: `10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe` + +`"compaction/prune"` + + + +#### `"compaction/start"` + +SHA-256: `e2d0367e5716bc188435e51718ebff8ce873190625fa93b1c5331102d98758fa` + +`"compaction/start"` + + + +#### `"compaction/summary"` + +SHA-256: `ef4f00923b9edbae15c7ef05320280bf61147ca17146cf59690359bfd5e5da45` + +`"compaction/summary"` + + + +#### `"complete"` + +SHA-256: `d9196086e41e4dd5c2ce87f5c25529c8112a1731d258cf0728747d41a9ee3241` + +`"complete"` + + + +#### `"completed"` + +SHA-256: `1ebc6f9ff3aa9e3a38f8695f49bacdab1f8b7a3832741853ca46f40af56ccd01` + +`"completed"` + + + +#### `"continuable"` + +SHA-256: `e5d3828df1ec3e2a66879de0659e0f4866d9cfffc00825ee731a66f8a0c03d98` + +`"continuable"` + + + +#### `"create"` + +SHA-256: `7624ca28c61ca0eaa4f015140f3cea6e0c16cce2f2960fab5f531203d253903e` + +`"create"` + + + +#### `"danger-full-access"` + +SHA-256: `18fce9540bb20897a66275499faee6b8296c97e9901fa1ff45a191772448ad1a` + +`"danger-full-access"` + + + +#### `"delegation"` + +SHA-256: `76632533f67879dcb346fcae640540dbc89b2472b0bce88c59f7e48fc5c0e668` + +`"delegation"` + + + +#### `"delete"` + +SHA-256: `d0fbb0ca1bbba059830826f33f801da1aced35a2504376d61e020bdfec8d50c0` + +`"delete"` + + + +#### `"deleted"` + +SHA-256: `e7e8f1318170b8284f16ab45a557afd4675c96071c0f2a456636481dab20b427` + +`"deleted"` + + + +#### `"deliverables/presented"` + +SHA-256: `1a2718b00937b236a0d0910ef5dab2f9f8b65e4bde410cc21f15fbbf29f584d3` + +`"deliverables/presented"` + + + +#### `"dispatch"` + +SHA-256: `26c879bdd130e8b8683a6ce588414fad2244783d6573ca399fa0de184a2b0bb1` + +`"dispatch"` + + + +#### `"disposed"` + +SHA-256: `b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751` + +`"disposed"` + + + +#### `"edit"` + +SHA-256: `ad22a5ca5bbaab2e1440779cd3648e85ddfc6f73b5207394eda699555cf31430` + +`"edit"` + + + +#### `"error"` + +SHA-256: `a2be0f0cb59f0d4a06557d45847d1938aced238baa77a6da416e590b8b958553` + +`"error"` + + + +#### `event:agent-preset/selected` + +SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:agent-preset/selected.data`](#persistence-type-eventagent-presetselecteddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"agent-preset/selected"` | + + + +#### `event:agent-preset/selected.data` + +SHA-256: `6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406` + +Sources: `packages/preset/agent-presets/src/session.ts` + +| Property | Presence | Type | +|---|---|---| +| `agentPreset` | required | `string` | + + + +#### `event:agent/inbox/spliced` + +SHA-256: `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:agent/inbox/spliced.data`](#persistence-type-eventagentinboxspliceddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"agent/inbox/spliced"` | + + + +#### `event:agent/inbox/spliced.data` + +SHA-256: `a6a195c1b4a906d953d24ab5864c9f1881d545460e080a51144adfc9cb058cfe` + +Sources: `packages/core/agent/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `inserted` | required | [`event:agent/inbox/spliced.data.inserted`](#persistence-type-eventagentinboxspliceddatainserted) | +| `outcome` | optional | `"canceled"` | +| `removedCount` | optional | `number` | +| `start` | required | `number` | +| `target` | required | [`packages/core/agent/src/types.ts#InboxTarget`](#persistence-type-packagescoreagentsrctypestsinboxtarget) | + + + +#### `event:agent/inbox/spliced.data.inserted` + +SHA-256: `300341f890f7b9506a1749fff4fa5239d16ea1c63ff6b15851acb03c20f3b48d` + +Array of [`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage). + + + +#### `event:agent/inbox/spliced.data.inserted[0].content` + +SHA-256: `bb72d86bc9ef0b3908bfa57ef98ccccae24d67d945c9f6869ca3cb8577889e75` + +Array of [`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock). + + + +#### `event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions` + +SHA-256: `0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef` + +Sources: `packages/attachment/attachment/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `height` | required | `number` | +| `width` | required | `number` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[0]` + +SHA-256: `ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05` + +Sources: `packages/core/session/src/types.ts` · `packages/interaction/commands/src/types.ts` · `packages/llm/llm/src/message.ts` · `packages/session/session-title/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"user"` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[1]` + +SHA-256: `0ddab4577db37a3e0d9e3a91761735c8ef6f5629d526ab8ecaeeea19c097c8f8` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[10]` + +SHA-256: `6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7` + +Sources: `packages/api/session-controller/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `clientTimeZone` | optional | `string` | +| `kind` | required | `"user"` | +| `rpcId` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[15].references` + +SHA-256: `df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18` + +Array of [`event:agent/inbox/spliced.data.inserted[0].source[15].references[0]`](#persistence-type-eventagentinboxspliceddatainserted0source15references0). + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[15].references[0]` + +SHA-256: `4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4` + +Sources: `packages/context/session-reference/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `capturedFormatVersion` | optional | `number` | +| `capturedThroughSeq` | required | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | +| `compacted` | required | `boolean` | +| `inputIndex` | required | `number` | +| `label` | required | `string` | +| `omittedBytes` | required | `number` | +| `omittedMessages` | required | `number` | +| `originalMessages` | required | `number` | +| `retainedMessages` | required | `number` | +| `sessionId` | required | `string` | +| `truncated` | required | `boolean` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[16].changes` + +SHA-256: `2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee` + +Array of [`packages/context/agent-instructions/src/render.ts#AgentInstructionChange`](#persistence-type-packagescontextagent-instructionssrcrendertsagentinstructionchange). + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action` + +SHA-256: `904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd` + +One of: + +- `"remove"` +- `"replace"` +- `"set"` + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[17].entries` + +SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` + +Array of [`event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]`](#persistence-type-eventagentinboxspliceddatainserted0source17entries0). + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]` + +SHA-256: `83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693` + +Sources: `packages/skill/tool-skill/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `description` | required | `string` | +| `name` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[19]` + +SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` + +Sources: `packages/webhook/webhook/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `deliveryId` | required | `string` | +| `form` | required | `"notice"` | +| `kind` | required | `"webhook"` | +| `provider` | required | `string` | +| `ruleId` | required | `string` | +| `source` | required | `string` | +| `summary` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[2]` + +SHA-256: `dda6e111a8ccfc12f6e742e977a1a4e3549e8c03732a5ff6c8d7c3d4bcb7a412` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[3]` + +SHA-256: `2f90a7b3646fea3e677bd7b4000aa96f3b8964f107b614e204e11ad4051c24fc` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"catalog"` | +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[4]` + +SHA-256: `e8d26e6993445743e6c4342c31b284c7d8f5574369abdd6021183af1a6b3538f` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"snapshot"` | +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | +| `sections` | required | [`event:agent/inbox/spliced.data.inserted[0].source[4].sections`](#persistence-type-eventagentinboxspliceddatainserted0source4sections) | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[4].sections` + +SHA-256: `c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262` + +Array of [`packages/llm/llm/src/message.ts#ContextSnapshotSection`](#persistence-type-packagesllmllmsrcmessagetscontextsnapshotsection). + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[5]` + +SHA-256: `b4d298d90c798fa4d1f5b030ce3ce8031c4c41beafdb05323bec8b2a06903b43` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | +| `summary` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[6]` + +SHA-256: `2ce7ef3b3daebf95815c7ae454a751d3e67ca7a22e2e0734fe2942df393bb66c` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[7]` + +SHA-256: `85e1bd563d6c80c1f377f99f91103fec4e315148a7330f3b3dae7c2d04e33b01` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"plugin"` | +| `plugin` | required | `string` | + + + +#### `event:approval/asked` + +SHA-256: `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:approval/asked.data`](#persistence-type-eventapprovalaskeddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"approval/asked"` | + + + +#### `event:approval/asked.data` + +SHA-256: `45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448` + +Sources: `packages/interaction/user-approval/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `callId` | optional | `string` | +| `id` | required | `string` | +| `reason` | optional | `string` | +| `toolName` | required | `string` | + + + +#### `event:approval/decided` + +SHA-256: `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:approval/decided.data`](#persistence-type-eventapprovaldecideddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"approval/decided"` | + + + +#### `event:approval/decided.data` + +SHA-256: `93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9` + +Sources: `packages/interaction/user-approval/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `outcome` | required | [`packages/interaction/user-approval/src/types.ts#ApprovalOutcome`](#persistence-type-packagesinteractionuser-approvalsrctypestsapprovaloutcome) | + + + +#### `event:approval/policy` + +SHA-256: `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:approval/policy.data`](#persistence-type-eventapprovalpolicydata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"approval/policy"` | + + + +#### `event:approval/policy.data` + +SHA-256: `11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912` + +Sources: `packages/interaction/user-approval/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `policy` | required | [`packages/interaction/user-approval/src/index.ts#ApprovalPolicy`](#persistence-type-packagesinteractionuser-approvalsrcindextsapprovalpolicy) | +| `source` | optional | `"delegation"` | + + + +#### `event:assistant/attempt` + +SHA-256: `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:assistant/attempt.data`](#persistence-type-eventassistantattemptdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"assistant/attempt"` | + + + +#### `event:assistant/attempt.data` + +SHA-256: `0c6412d3ba5e41adfaa6929c7d4093f2d52d8598c03f35844fc0d55e3070a3b1` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `step` | required | `number` | +| `stream` | required | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | +| `turn` | required | `number` | + + + +#### `event:assistant/attempt.data.stream` + +SHA-256: `26f3bb7529cfce1e3a0f1ededa365d8b426758ca0feeb0beabeee805f8bb8346` + +Array of [`packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord`](#persistence-type-packagesllmllmsrcassistant-streamtsassistantstreamrecord). + + + +#### `event:assistant/attempt.data.stream[0][0]` + +SHA-256: `e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33` + +Sources: `packages/llm/llm/src/assistant-stream.ts` + +| Property | Presence | Type | +|---|---|---| +| `dt` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `index` | required | `number` | +| `texts` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `time0` | required | `number` | +| `type` | required | `"text-chunks"` | + + + +#### `event:assistant/attempt.data.stream[0][0].texts` + +SHA-256: `93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2` + +Array of `string`. + + + +#### `event:assistant/attempt.data.stream[0][1]` + +SHA-256: `71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd` + +Sources: `packages/llm/llm/src/assistant-stream.ts` + +| Property | Presence | Type | +|---|---|---| +| `dt` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `index` | required | `number` | +| `texts` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `time0` | required | `number` | +| `type` | required | `"reasoning-chunks"` | + + + +#### `event:assistant/attempt.data.stream[0][2]` + +SHA-256: `3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6` + +Sources: `packages/llm/llm/src/assistant-stream.ts` + +| Property | Presence | Type | +|---|---|---| +| `args` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `dt` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `id` | required | `string` | +| `index` | required | `number` | +| `name` | optional | `string` | +| `time0` | required | `number` | +| `type` | required | `"tool-call-chunks"` | + + + +#### `event:assistant/attempt.data.stream[0][3]` + +SHA-256: `c93b6f51b399607349b4bcc66b58e848a44250ffc1e2537207bd092dfff94192` + +Sources: `packages/llm/llm/src/assistant-stream.ts` + +| Property | Presence | Type | +|---|---|---| +| `chunk` | required | [`packages/llm/llm/src/types.ts#StreamChunk`](#persistence-type-packagesllmllmsrctypestsstreamchunk) | +| `time` | required | `number` | +| `type` | required | `"chunk"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[0]` + +SHA-256: `647cb2e3aeb58e27d1d4d60011f208bb66dce257e8654193c533b47c4c22c253` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `blockType` | required | [`packages/llm/llm/src/types.ts#ContentBlockType`](#persistence-type-packagesllmllmsrctypestscontentblocktype) | +| `index` | required | `number` | +| `type` | required | `"block-start"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[1]` + +SHA-256: `95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `index` | required | `number` | +| `text` | required | `string` | +| `type` | required | `"text-delta"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[2]` + +SHA-256: `2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `index` | required | `number` | +| `text` | required | `string` | +| `type` | required | `"reasoning-delta"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[3]` + +SHA-256: `88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `argumentsDelta` | required | `string` | +| `id` | required | `string` | +| `index` | required | `number` | +| `name` | optional | `string` | +| `type` | required | `"tool-call-delta"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[4]` + +SHA-256: `90c811b8c2668898515e69a24e82caffeb08517f9c7aa193867ff0380f3b535d` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `block` | required | [`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock) | +| `index` | required | `number` | +| `type` | required | `"block-end"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[5]` + +SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `type` | required | `"usage"` | +| `usage` | required | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6]` + +SHA-256: `a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `reason` | required | [`packages/llm/llm/src/types.ts#FinishReason`](#persistence-type-packagesllmllmsrctypestsfinishreason) | +| `replayState` | optional | [`packages/llm/llm/src/types.ts#ReplayEnvelope`](#persistence-type-packagesllmllmsrctypestsreplayenvelope) | +| `type` | required | `"finish"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]` + +SHA-256: `8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `kind` | required | `"aborted"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]` + +SHA-256: `693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `kind` | required | `"error"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]` + +SHA-256: `ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7` + +Sources: `packages/core/session/src/types.ts` · `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"max-tokens"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]` + +SHA-256: `1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"stop"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]` + +SHA-256: `287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"tool-calls"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks` + +SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7` + +Array of `unknown` (opaque). + + + +#### `event:assistant/message` + +SHA-256: `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:assistant/message.data`](#persistence-type-eventassistantmessagedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | required | `number` | +| `type` | required | `"assistant/message"` | + + + +#### `event:assistant/message.data` + +SHA-256: `77b8491f946edfc8cc77ebae3ba49183759da31ba2dfa83d4c9e9e618c4b91d2` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `interrupted` | optional | `true` | +| `message` | required | [`packages/llm/llm/src/message.ts#AssistantMessage`](#persistence-type-packagesllmllmsrcmessagetsassistantmessage) | +| `step` | required | `number` | +| `stream` | required | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | +| `turn` | required | `number` | +| `usage` | optional | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:command/done` + +SHA-256: `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:command/done.data`](#persistence-type-eventcommanddonedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"command/done"` | + + + +#### `event:command/done.data` + +SHA-256: `5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51` + +Sources: `packages/interaction/commands/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `commandId` | required | `string` | +| `kind` | required | [`event:command/done.data.kind`](#persistence-type-eventcommanddonedatakind) | +| `sourceEventSeq` | optional | `number` | +| `text` | optional | `string` | + + + +#### `event:command/done.data.kind` + +SHA-256: `1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92` + +One of: + +- `"error"` +- `"success"` + + + +#### `event:command/run` + +SHA-256: `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:command/run.data`](#persistence-type-eventcommandrundata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"command/run"` | + + + +#### `event:command/run.data` + +SHA-256: `a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86` + +Sources: `packages/interaction/commands/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `args` | optional | `string` | +| `commandId` | required | `string` | +| `name` | required | `string` | +| `source` | required | [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) | + + + +#### `event:compaction/end` + +SHA-256: `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:compaction/end.data`](#persistence-type-eventcompactionenddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/end"` | + + + +#### `event:compaction/end.data` + +SHA-256: `ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2` + +Sources: `packages/compaction/compaction/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `error` | optional | `string` | +| `sourceCommandId` | optional | `string` | +| `turn` | required | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | + + + +#### `event:compaction/end.data.turn` + +SHA-256: `3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f` + +Sources: `packages/core/session/src/types.ts` + +One of: + +- `null` +- `number` + + + +#### `event:compaction/prune` + +SHA-256: `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:compaction/prune.data`](#persistence-type-eventcompactionprunedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/prune"` | + + + +#### `event:compaction/prune.data` + +SHA-256: `5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438` + +Sources: `packages/compaction/compaction/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `shadowedRange` | required | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | +| `shadowedSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `shadowedTokenCount` | required | `number` | + + + +#### `event:compaction/prune.data.shadowedRange` + +SHA-256: `9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2` + +Sources: `packages/compaction/compaction/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `end` | required | `number` | +| `start` | required | `number` | + + + +#### `event:compaction/start` + +SHA-256: `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:compaction/start.data`](#persistence-type-eventcompactionstartdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/start"` | + + + +#### `event:compaction/start.data` + +SHA-256: `3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f` + +Sources: `packages/compaction/compaction/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `sourceCommandId` | optional | `string` | +| `turn` | required | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | + + + +#### `event:compaction/summary` + +SHA-256: `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:compaction/summary.data`](#persistence-type-eventcompactionsummarydata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"compaction/summary"` | + + + +#### `event:compaction/summary.data` + +SHA-256: `feb329074f0206ecc06d8a1aa0a0b3e2f47fd27524ba020fbc849ba63e938896` + +One of: + +- [`event:compaction/summary.data[0]`](#persistence-type-eventcompactionsummarydata0) +- [`event:compaction/summary.data[1]`](#persistence-type-eventcompactionsummarydata1) + + + +#### `event:compaction/summary.data[0]` + +SHA-256: `9ff2ad8dddb836f75e8f6197fff2371323dfc396c3c6fb667e6e0b42fda79a5c` + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `llmStreamCall` | required | `true` | +| `maxTokens` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `rawOutput` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `shadowedRange` | required | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | +| `shadowedSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `shadowedTokenCount` | required | `number` | +| `sourceCommandId` | optional | `string` | +| `summary` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `usage` | optional | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:compaction/summary.data[1]` + +SHA-256: `3aa261c8516b5c955ed12080e6257a56cbe513f6c9f0ac9274c12e96c196ebca` + +| Property | Presence | Type | +|---|---|---| +| `compactionId` | required | `string` | +| `maxTokens` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `rawOutput` | optional | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `shadowedRange` | required | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | +| `shadowedSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `shadowedTokenCount` | required | `number` | +| `sourceCommandId` | optional | `string` | +| `summary` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `usage` | optional | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:deliverables/presented` + +SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:deliverables/presented.data`](#persistence-type-eventdeliverablespresenteddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"deliverables/presented"` | + + + +#### `event:deliverables/presented.data` + +SHA-256: `1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c` + +Sources: `packages/fs/tool-present/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `callId` | required | `string` | +| `files` | required | [`event:deliverables/presented.data.files`](#persistence-type-eventdeliverablespresenteddatafiles) | +| `turn` | required | `number` | + + + +#### `event:deliverables/presented.data.files` + +SHA-256: `1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345` + +Array of [`packages/fs/tool-present/src/types.ts#PresentedFile`](#persistence-type-packagesfstool-presentsrctypestspresentedfile). + + + +#### `event:feedback/message-delete` + +SHA-256: `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackdelete) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"feedback/message-delete"` | + + + +#### `event:feedback/message-put` + +SHA-256: `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackput) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"feedback/message-put"` | + + + +#### `event:feedback/message-put.data.item.category` + +SHA-256: `3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd` + +One of: + +- `"instruction-following"` +- `"other"` +- `"product-interaction"` +- `"resource-cost"` +- `"security-privacy-permission"` +- `"service-stability"` +- `"task-result"` + + + +#### `event:feedback/record` + +SHA-256: `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/feedback/command-feedback/src/types.ts#FeedbackRecord`](#persistence-type-packagesfeedbackcommand-feedbacksrctypestsfeedbackrecord) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"feedback/record"` | + + + +#### `event:goal/change` + +SHA-256: `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/goal/goal/src/domain.ts#GoalChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalchangemeta) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"goal/change"` | + + + +#### `event:goal/change.data[0].operation` + +SHA-256: `62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379` + +One of: + +- `"block"` +- `"complete"` +- `"create"` +- `"edit"` +- `"pause"` +- `"resume"` + + + +#### `event:hook/invoked` + +SHA-256: `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:hook/invoked.data`](#persistence-type-eventhookinvokeddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"hook/invoked"` | + + + +#### `event:hook/invoked.data` + +SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` + +Sources: `packages/hooks/hook-protocol/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `dialect` | required | [`packages/hooks/hook-protocol/src/types.ts#HookDialect`](#persistence-type-packageshookshook-protocolsrctypestshookdialect) | +| `handlerId` | required | `string` | +| `matcher` | optional | `string` | +| `point` | required | `string` | +| `turn` | required | `number` | + + + +#### `event:hook/result` + +SHA-256: `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:hook/result.data`](#persistence-type-eventhookresultdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"hook/result"` | + + + +#### `event:hook/result.data` + +SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` + +Sources: `packages/hooks/hook-protocol/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `decision` | required | `string` | +| `durationMs` | required | `number` | +| `exitCode` | optional | `number` | +| `handlerId` | required | `string` | +| `point` | required | `string` | +| `stderrSummary` | optional | `string` | +| `turn` | required | `number` | + + + +#### `event:image/offload` + +SHA-256: `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:image/offload.data`](#persistence-type-eventimageoffloaddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"image/offload"` | + + + +#### `event:image/offload.data` + +SHA-256: `477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028` + +Sources: `packages/compaction/compaction-image-offload/src/projection.ts` + +| Property | Presence | Type | +|---|---|---| +| `targets` | required | [`event:image/offload.data.targets`](#persistence-type-eventimageoffloaddatatargets) | + + + +#### `event:image/offload.data.targets` + +SHA-256: `9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb` + +Array of [`packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget`](#persistence-type-packagescompactioncompaction-image-offloadsrcprojectiontsimageoffloadtarget). + + + +#### `event:llm/retry` + +SHA-256: `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/llm/llm-retry/src/types.ts#LlmRetryEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretryeventdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"llm/retry"` | + + + +#### `event:llm/retry-started` + +SHA-256: `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretrystartedeventdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"llm/retry-started"` | + + + +#### `event:llm/retry.data[0]` + +SHA-256: `cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced` + +Sources: `packages/llm/llm-retry/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `delayMs` | required | `number` | +| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `maxRetries` | required | `number` | +| `mode` | required | `"normal"` | +| `policyKey` | required | `string` | +| `provider` | required | `string` | +| `retry` | required | `number` | +| `retryId` | required | `string` | +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `event:llm/retry.data[1]` + +SHA-256: `374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b` + +Sources: `packages/llm/llm-retry/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `delayMs` | required | `number` | +| `failure` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `mode` | required | `"always"` | +| `policyKey` | required | `string` | +| `provider` | required | `string` | +| `retry` | required | `number` | +| `retryId` | required | `string` | +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `event:model/selection` + +SHA-256: `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/api/session-controller/src/types.ts#ModelSelection`](#persistence-type-packagesapisession-controllersrctypestsmodelselection) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"model/selection"` | + + + +#### `event:permission/preset` + +SHA-256: `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:permission/preset.data`](#persistence-type-eventpermissionpresetdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"permission/preset"` | + + + +#### `event:permission/preset.data` + +SHA-256: `8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad` + +Sources: `packages/interaction/permission-presets/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `preset` | required | `string` | + + + +#### `event:plan/mode` + +SHA-256: `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:plan/mode.data`](#persistence-type-eventplanmodedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"plan/mode"` | + + + +#### `event:plan/mode.data` + +SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5` + +Sources: `packages/plan/plan-mode/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `active` | required | `boolean` | + + + +#### `event:request/context` + +SHA-256: `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/core/session/src/types.ts#RequestContext`](#persistence-type-packagescoresessionsrctypestsrequestcontext) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"request/context"` | + + + +#### `event:request/header` + +SHA-256: `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:request/header.data`](#persistence-type-eventrequestheaderdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"request/header"` | + + + +#### `event:request/header.data` + +SHA-256: `2f0aefb72ab453c4bf21a6687f436775d359dc6f8f10410fd4c0615b20bd9d76` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `header` | required | [`packages/core/session/src/types.ts#EpochHeader`](#persistence-type-packagescoresessionsrctypestsepochheader) | +| `reason` | required | [`packages/core/session/src/types.ts#RequestHeaderReason`](#persistence-type-packagescoresessionsrctypestsrequestheaderreason) | +| `startsSeries` | optional | `true` | + + + +#### `event:request/header.data.header.tools` + +SHA-256: `6d63f25a28b70801937a46b1058be5f52d4efbaf3516141470463ae469b59c23` + +Array of [`packages/llm/llm/src/types.ts#ToolSchema`](#persistence-type-packagesllmllmsrctypeststoolschema). + + + +#### `event:request/header.data.header.tools[0].parameters` + +SHA-256: `0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f` + +| Property | Presence | Type | +|---|---|---| +| [`string`] | index signature | `unknown` (opaque) | + + + +#### `event:sandbox/mode` + +SHA-256: `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:sandbox/mode.data`](#persistence-type-eventsandboxmodedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"sandbox/mode"` | + + + +#### `event:sandbox/mode.data` + +SHA-256: `9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e` + +Sources: `packages/sandbox/sandbox-policy/src/session-mode.ts` + +| Property | Presence | Type | +|---|---|---| +| `mode` | required | [`packages/sandbox/sandbox/src/index.ts#SandboxMode`](#persistence-type-packagessandboxsandboxsrcindextssandboxmode) | +| `source` | optional | `"delegation"` | + + + +#### `event:schedule/change` + +SHA-256: `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/schedule/schedule/src/types.ts#ScheduleChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulechange) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"schedule/change"` | + + + +#### `event:session-log-deepseek/delivery-accepted` + +SHA-256: `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:session-log-deepseek/delivery-accepted.data`](#persistence-type-eventsession-log-deepseekdelivery-accepteddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session-log-deepseek/delivery-accepted"` | + + + +#### `event:session-log-deepseek/delivery-accepted.data` + +SHA-256: `8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52` + +Sources: `packages/session/session-log-deepseek/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `sessionFormatVersion` | optional | `number` | +| `sessionId` | required | `string` | +| `throughSeq` | required | `number` | + + + +#### `event:session/end-seed` + +SHA-256: `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:session/end-seed.data`](#persistence-type-eventsessionend-seeddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session/end-seed"` | + + + +#### `event:session/end-seed.data` + +SHA-256: `17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `inherited` | optional | `true` | + + + +#### `event:session/title` + +SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/session/session-title/src/types.ts#SessionTitleEventData`](#persistence-type-packagessessionsession-titlesrctypestssessiontitleeventdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session/title"` | + + + +#### `event:session/title-llm-request` + +SHA-256: `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData`](#persistence-type-packagessessionsession-title-llmsrcindextssessiontitlellmrequesteventdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"session/title-llm-request"` | + + + +#### `event:session/title-llm-request.data.messages` + +SHA-256: `478738df7e7d2b103b09fb937817a9302c81076809f2b341169e00a9419c5665` + +Array of [`packages/llm/llm/src/message.ts#Message`](#persistence-type-packagesllmllmsrcmessagetsmessage). + + + +#### `event:session/title-llm-request.data.messages[0].role` + +SHA-256: `acd36e1717d2b4ef9e98a8e6fac17ca1203f3f448e5bca51677f129a8f4999e2` + +One of: + +- `"assistant"` +- `"system"` +- `"user"` + + + +#### `event:session/title.data.source[0]` + +SHA-256: `1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597` + +Sources: `packages/session/session-title/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"fallback"` | + + + +#### `event:session/title.data.source[1]` + +SHA-256: `b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812` + +Sources: `packages/session/session-title/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"provider"` | +| `model` | optional | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | +| `provider` | required | `string` | + + + +#### `event:step/end` + +SHA-256: `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:step/end.data`](#persistence-type-eventstependdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"step/end"` | + + + +#### `event:step/end.data` + +SHA-256: `ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `event:step/start` + +SHA-256: `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:step/end.data`](#persistence-type-eventstependdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"step/start"` | + + + +#### `event:subagent/catalog` + +SHA-256: `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent`](#persistence-type-packagessubagentsubagentsrccatalogtssubagentcatalogevent) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"subagent/catalog"` | + + + +#### `event:subagent/catalog.data[0]` + +SHA-256: `5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694` + +| Property | Presence | Type | +|---|---|---| +| `childCreatedAt` | required | `number` | +| `childId` | required | `string` | +| `label` | optional | `string` | +| `mode` | required | `"one-shot"` | +| `version` | required | `0` | + + + +#### `event:subagent/catalog.data[1]` + +SHA-256: `0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd` + +| Property | Presence | Type | +|---|---|---| +| `childCreatedAt` | required | `number` | +| `childId` | required | `string` | +| `label` | required | `string` | +| `mode` | required | `"continuable"` | +| `version` | required | `0` | + + + +#### `event:subagent/descriptor` + +SHA-256: `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortssubagentdescriptordata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"subagent/descriptor"` | + + + +#### `event:subagent/model-selection-policy` + +SHA-256: `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:subagent/model-selection-policy.data`](#persistence-type-eventsubagentmodel-selection-policydata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"subagent/model-selection-policy"` | + + + +#### `event:subagent/model-selection-policy.data` + +SHA-256: `0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f` + +Sources: `packages/subagent/tool-subagent/src/model-selection-state.ts` + +| Property | Presence | Type | +|---|---|---| +| `allowedModels` | required | [`event:subagent/model-selection-policy.data.allowedModels`](#persistence-type-eventsubagentmodel-selection-policydataallowedmodels) | + + + +#### `event:subagent/model-selection-policy.data.allowedModels` + +SHA-256: `ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec` + +Array of [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity). + + + +#### `event:system/message` + +SHA-256: `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:system/message.data`](#persistence-type-eventsystemmessagedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | required | `number` | +| `type` | required | `"system/message"` | + + + +#### `event:system/message.data` + +SHA-256: `2074f40221b76c75fd314246db558965dc3477dfb440bcc952b1eedc9778e366` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `message` | required | [`packages/llm/llm/src/message.ts#SystemMessage`](#persistence-type-packagesllmllmsrcmessagetssystemmessage) | +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `event:system/message.data.message.source` + +SHA-256: `23cf7e0cf3fec1283b60fa15713506169bc9c079a08e124d1cb9733baca80b40` + +One of: + +- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) +- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) +- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) +- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) +- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) +- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) +- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) + + + +#### `event:team/member` + +SHA-256: `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:team/member.data`](#persistence-type-eventteammemberdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/member"` | + + + +#### `event:team/member.data` + +SHA-256: `b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `member` | required | [`packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammembersnapshot) | +| `teamId` | required | `string` | +| `version` | required | `2` | + + + +#### `event:team/member.data.member.context` + +SHA-256: `50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48` + +One of: + +- `"fork"` +- `"fresh"` + + + +#### `event:team/message/delivered` + +SHA-256: `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:team/message/delivered.data`](#persistence-type-eventteammessagedelivereddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/message/delivered"` | + + + +#### `event:team/message/delivered.data` + +SHA-256: `0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `messageId` | required | `string` | +| `targetId` | required | `string` | +| `teamId` | required | `string` | +| `version` | required | `2` | + + + +#### `event:team/message/queued` + +SHA-256: `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:team/message/queued.data`](#persistence-type-eventteammessagequeueddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/message/queued"` | + + + +#### `event:team/message/queued.data` + +SHA-256: `0c3f4d2248d9bc9700e2d7253fa71aa9935f5c39af6f11de5727f08cccaf8383` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `message` | required | [`packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesnapshot) | +| `teamId` | required | `string` | +| `version` | required | `2` | + + + +#### `event:team/task` + +SHA-256: `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:team/task.data`](#persistence-type-eventteamtaskdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"team/task"` | + + + +#### `event:team/task.data` + +SHA-256: `a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `task` | required | [`packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtasksnapshot) | +| `teamId` | required | `string` | +| `version` | required | `2` | + + + +#### `event:todo/write` + +SHA-256: `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:todo/write.data`](#persistence-type-eventtodowritedata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"todo/write"` | + + + +#### `event:todo/write.data` + +SHA-256: `79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99` + +Sources: `packages/todo/tool-todo/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `todos` | required | [`event:todo/write.data.todos`](#persistence-type-eventtodowritedatatodos) | + + + +#### `event:todo/write.data.todos` + +SHA-256: `4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea` + +Array of [`packages/todo/tool-todo/src/types.ts#TodoItem`](#persistence-type-packagestodotool-todosrctypeststodoitem). + + + +#### `event:todo/write.data.todos[0].status` + +SHA-256: `fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4` + +One of: + +- `"completed"` +- `"in_progress"` +- `"pending"` + + + +#### `event:tool-workflow/agent-end` + +SHA-256: `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentenddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/agent-end"` | + + + +#### `event:tool-workflow/agent-start` + +SHA-256: `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentstartdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/agent-start"` | + + + +#### `event:tool-workflow/run-end` + +SHA-256: `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunenddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/run-end"` | + + + +#### `event:tool-workflow/run-start` + +SHA-256: `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunstartdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool-workflow/run-start"` | + + + +#### `event:tool/call` + +SHA-256: `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:tool/call.data`](#persistence-type-eventtoolcalldata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool/call"` | + + + +#### `event:tool/call.data` + +SHA-256: `e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `string` | +| `callId` | required | `string` | +| `name` | required | `string` | +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `event:tool/ptc-dispatch` + +SHA-256: `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/core/tools/src/types.ts#PtcDispatchEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatcheventdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool/ptc-dispatch"` | + + + +#### `event:tool/ptc-dispatch-start` + +SHA-256: `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/core/tools/src/types.ts#PtcDispatchStartEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatchstarteventdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"tool/ptc-dispatch-start"` | + + + +#### `event:tool/ptc-dispatch.data.error` + +SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735` + +Sources: `packages/core/session/src/types.ts` · `packages/core/tools/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `code` | required | `string` | +| `name` | required | `string` | +| `reason` | optional | `string` | + + + +#### `event:tool/result` + +SHA-256: `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:tool/result.data`](#persistence-type-eventtoolresultdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | required | `number` | +| `type` | required | `"tool/result"` | + + + +#### `event:tool/result.data` + +SHA-256: `356aad27134a0e31af67c994ff8b9e4b91acfb6c4917b3bc1f7a62bbf82794d5` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `error` | optional | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | +| `message` | required | [`packages/llm/llm/src/message.ts#ToolResultMessage`](#persistence-type-packagesllmllmsrcmessagetstoolresultmessage) | +| `meta` | optional | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `event:tool/result.data.message.content` + +SHA-256: `8d6a011f3ef7096a4a922ef420458419ff6b20e1eaeece5d331db7585d2f08d6` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) | + + + +#### `event:tool/result.data.meta` + +SHA-256: `c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6` + +Sources: `packages/util/values/src/index.ts` + +One of: + +- [`event:tool/result.data.meta[5]`](#persistence-type-eventtoolresultdatameta5) +- [`event:tool/result.data.meta[5][0][6]`](#persistence-type-eventtoolresultdatameta506) +- `string` +- `boolean` +- `null` +- `number` + + + +#### `event:tool/result.data.meta[5]` + +SHA-256: `72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227` + +Array of [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta). + + + +#### `event:tool/result.data.meta[5][0][6]` + +SHA-256: `529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05` + +Sources: `packages/util/values/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| [`string`] | index signature | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | + + + +#### `event:turn/end` + +SHA-256: `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:turn/end.data`](#persistence-type-eventturnenddata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"turn/end"` | + + + +#### `event:turn/end.data` + +SHA-256: `d3e447062a2847dad847dad5168a9508d92c484363dfc76fd82605aa7bd46285` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `reason` | required | [`packages/core/session/src/types.ts#TurnEndReason`](#persistence-type-packagescoresessionsrctypeststurnendreason) | +| `turn` | required | `number` | + + + +#### `event:turn/end.data.reason[0]` + +SHA-256: `b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"completed"` | + + + +#### `event:turn/end.data.reason[1]` + +SHA-256: `0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"aborted"` | +| `reason` | required | [`packages/core/session/src/types.ts#TurnEndCancelCause`](#persistence-type-packagescoresessionsrctypeststurnendcancelcause) | + + + +#### `event:turn/end.data.reason[1].reason[1]` + +SHA-256: `6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"parent"` | + + + +#### `event:turn/end.data.reason[1].reason[2]` + +SHA-256: `6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"hook"` | +| `reason` | required | `string` | + + + +#### `event:turn/end.data.reason[1].reason[3]` + +SHA-256: `4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"disposed"` | + + + +#### `event:turn/end.data.reason[1].reason[4]` + +SHA-256: `eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"legacy"` | + + + +#### `event:turn/end.data.reason[2]` + +SHA-256: `023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"blocked"` | + + + +#### `event:turn/end.data.reason[3]` + +SHA-256: `79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `error` | required | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `kind` | required | `"error"` | + + + +#### `event:turn/end.data.reason[5]` + +SHA-256: `56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"interrupted"` | + + + +#### `event:turn/start` + +SHA-256: `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`event:turn/start.data`](#persistence-type-eventturnstartdata) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"turn/start"` | + + + +#### `event:turn/start.data` + +SHA-256: `f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `turn` | required | `number` | + + + +#### `event:user/message` + +SHA-256: `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | required | `number` | +| `type` | required | `"user/message"` | + + + +#### `event:web/deepseek-search-llm-request` + +SHA-256: `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` + +| Property | Presence | Type | +|---|---|---| +| `data` | required | [`packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest`](#persistence-type-packageswebweb-search-deepseeksrcprovidertsdeepseeksearchllmrequest) | +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `"web/deepseek-search-llm-request"` | + + + +#### `event:web/deepseek-search-llm-request.data.body` + +SHA-256: `930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731` + +Sources: `packages/web/web-search-deepseek/src/provider.ts` + +| Property | Presence | Type | +|---|---|---| +| `max_tokens` | required | `number` | +| `messages` | required | [`event:web/deepseek-search-llm-request.data.body.messages`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages) | +| `model` | required | `string` | +| `tools` | required | [`event:web/deepseek-search-llm-request.data.body.tools`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools) | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages` + +SHA-256: `b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`event:web/deepseek-search-llm-request.data.body.messages[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0) | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages[0]` + +SHA-256: `9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5` + +Sources: `packages/web/web-search-deepseek/src/provider.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:web/deepseek-search-llm-request.data.body.messages[0].content`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content) | +| `role` | required | `"user"` | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages[0].content` + +SHA-256: `8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages[0].content[0]` + +SHA-256: `4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c` + +Sources: `packages/llm/llm/src/types.ts` · `packages/web/web-search-deepseek/src/provider.ts` + +| Property | Presence | Type | +|---|---|---| +| `text` | required | `string` | +| `type` | required | `"text"` | + + + +#### `event:web/deepseek-search-llm-request.data.body.tools` + +SHA-256: `4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8` + +| Position | Presence | Type | +|---|---|---| +| 0 | required | [`event:web/deepseek-search-llm-request.data.body.tools[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools0) | + + + +#### `event:web/deepseek-search-llm-request.data.body.tools[0]` + +SHA-256: `2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3` + +Sources: `packages/web/web-search-deepseek/src/provider.ts` + +| Property | Presence | Type | +|---|---|---| +| `max_uses` | required | `number` | +| `name` | required | `"web_search"` | +| `type` | required | `"web_search_20250305"` | + + + +#### `"every"` + +SHA-256: `e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87` + +`"every"` + + + +#### `"failed"` + +SHA-256: `b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420` + +`"failed"` + + + +#### `"fallback"` + +SHA-256: `d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c` + +`"fallback"` + + + +#### `"feedback/message-delete"` + +SHA-256: `44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e` + +`"feedback/message-delete"` + + + +#### `"feedback/message-put"` + +SHA-256: `6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8` + +`"feedback/message-put"` + + + +#### `"feedback/record"` + +SHA-256: `c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954` + +`"feedback/record"` + + + +#### `"file"` + +SHA-256: `277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9` + +`"file"` + + + +#### `"finish"` + +SHA-256: `bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd` + +`"finish"` + + + +#### `"fork"` + +SHA-256: `2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863` + +`"fork"` + + + +#### `"fresh"` + +SHA-256: `dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d` + +`"fresh"` + + + +#### `"goal"` + +SHA-256: `b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602` + +`"goal"` + + + +#### `"goal/change"` + +SHA-256: `237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163` + +`"goal/change"` + + + +#### `"hook"` + +SHA-256: `dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc` + +`"hook"` + + + +#### `"hook/invoked"` + +SHA-256: `b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611` + +`"hook/invoked"` + + + +#### `"hook/result"` + +SHA-256: `a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2` + +`"hook/result"` + + + +#### `"image"` + +SHA-256: `fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0` + +`"image"` + + + +#### `"image/gif"` + +SHA-256: `de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048` + +`"image/gif"` + + + +#### `"image/jpeg"` + +SHA-256: `3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004` + +`"image/jpeg"` + + + +#### `"image/offload"` + +SHA-256: `9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49` + +`"image/offload"` + + + +#### `"image/png"` + +SHA-256: `58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0` + +`"image/png"` + + + +#### `"image/webp"` + +SHA-256: `ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8` + +`"image/webp"` + + + +#### `"in-history"` + +SHA-256: `f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5` + +Sources: `packages/llm/llm/src/types.ts` + +`"in-history"` + + + +#### `"in_progress"` + +SHA-256: `94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378` + +`"in_progress"` + + + +#### `"initial"` + +SHA-256: `e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c` + +`"initial"` + + + +#### `"instruction-following"` + +SHA-256: `e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486` + +`"instruction-following"` + + + +#### `"instructions"` + +SHA-256: `fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5` + +`"instructions"` + + + +#### `"interrupted"` + +SHA-256: `69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199` + +`"interrupted"` + + + +#### `"legacy"` + +SHA-256: `ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc` + +`"legacy"` + + + +#### `"llm/retry"` + +SHA-256: `611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d` + +`"llm/retry"` + + + +#### `"llm/retry-started"` + +SHA-256: `4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964` + +`"llm/retry-started"` + + + +#### `"max-tokens"` + +SHA-256: `68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe` + +`"max-tokens"` + + + +#### `"model"` + +SHA-256: `2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e` + +`"model"` + + + +#### `"model/selection"` + +SHA-256: `1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2` + +`"model/selection"` + + + +#### `"negative"` + +SHA-256: `b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5` + +`"negative"` + + + +#### `"never"` + +SHA-256: `1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b` + +`"never"` + + + +#### `"next-step"` + +SHA-256: `3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693` + +`"next-step"` + + + +#### `"next-turn"` + +SHA-256: `62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd` + +`"next-turn"` + + + +#### `"normal"` + +SHA-256: `3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79` + +`"normal"` + + + +#### `"notice"` + +SHA-256: `e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367` + +`"notice"` + + + +#### `null` + +SHA-256: `938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615` + +`null` + + + +#### `number` + +SHA-256: `0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7` + +Sources: `packages/core/session/src/types.ts` + +`number` + + + +#### `"one-shot"` + +SHA-256: `d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2` + +`"one-shot"` + + + +#### `"other"` + +SHA-256: `9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4` + +`"other"` + + + +#### `packages/api/session-controller/src/types.ts#ModelSelection` + +SHA-256: `f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b` + +Sources: `packages/api/session-controller/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `model` | required | `string` | +| `provider` | required | `string` | +| `reasoningEffort` | optional | `string` | + + + +#### `packages/attachment/attachment/src/types.ts#FileAttachmentRef` + +SHA-256: `f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6` + +Sources: `packages/attachment/attachment/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `attachmentId` | required | `string` | +| `bytes` | required | `number` | +| `name` | required | `string` | + + + +#### `packages/attachment/attachment/src/types.ts#ImageAttachmentRef` + +SHA-256: `b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35` + +Sources: `packages/attachment/attachment/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `attachmentId` | required | `string` | +| `bytes` | required | `number` | +| `height` | required | `number` | +| `mediaType` | required | [`packages/attachment/attachment/src/types.ts#ImageMediaType`](#persistence-type-packagesattachmentattachmentsrctypestsimagemediatype) | +| `name` | optional | `string` | +| `originalDimensions` | optional | [`event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions`](#persistence-type-eventagentinboxspliceddatainserted0content02attachmentoriginaldimensions) | +| `width` | required | `number` | + + + +#### `packages/attachment/attachment/src/types.ts#ImageMediaType` + +SHA-256: `2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716` + +Sources: `packages/attachment/attachment/src/types.ts` + +One of: + +- `"image/gif"` +- `"image/jpeg"` +- `"image/png"` +- `"image/webp"` + + + +#### `packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget` + +SHA-256: `1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f` + +Sources: `packages/compaction/compaction-image-offload/src/projection.ts` + +| Property | Presence | Type | +|---|---|---| +| `imageIndexes` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `seq` | required | `number` | + + + +#### `packages/context/agent-instructions/src/render.ts#AgentInstructionChange` + +SHA-256: `83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239` + +Sources: `packages/context/agent-instructions/src/render.ts` + +| Property | Presence | Type | +|---|---|---| +| `action` | required | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action`](#persistence-type-eventagentinboxspliceddatainserted0source16changes0action) | +| `digest` | optional | `string` | +| `path` | required | `string` | +| `scope` | required | `string` | + + + +#### `packages/context/agent-instructions/src/state.ts#AgentInstructionSource` + +SHA-256: `6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590` + +Sources: `packages/context/agent-instructions/src/state.ts` + +| Property | Presence | Type | +|---|---|---| +| `baseline` | optional | `true` | +| `baselineIdentity` | optional | `string` | +| `changes` | required | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes`](#persistence-type-eventagentinboxspliceddatainserted0source16changes) | +| `form` | required | `"instructions"` | +| `kind` | required | `"agent-instructions"` | + + + +#### `packages/context/session-reference/src/types.ts#SessionReferenceSource` + +SHA-256: `f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f` + +Sources: `packages/context/session-reference/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"recall"` | +| `kind` | required | `"session-reference"` | +| `references` | required | [`event:agent/inbox/spliced.data.inserted[0].source[15].references`](#persistence-type-eventagentinboxspliceddatainserted0source15references) | +| `version` | required | `1` | + + + +#### `packages/core/agent/src/types.ts#InboxTarget` + +SHA-256: `96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c` + +Sources: `packages/core/agent/src/types.ts` + +One of: + +- `"next-step"` +- `"next-turn"` + + + +#### `packages/core/session/src/types.ts#EpochHeader` + +SHA-256: `c55a891c7aac496de6ee64c91c1fb65728c977314013033e42c863428aada854` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `adapterDefaults` | optional | [`packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfigadapterdefaults) | +| `config` | required | [`packages/llm/llm/src/call-config.ts#LlmCallConfig`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfig) | +| `tools` | optional | [`event:request/header.data.header.tools`](#persistence-type-eventrequestheaderdataheadertools) | + + + +#### `packages/core/session/src/types.ts#RequestContext` + +SHA-256: `b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `contextWindow` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `systemPromptUpdate` | optional | `"in-history"` | + + + +#### `packages/core/session/src/types.ts#RequestHeaderReason` + +SHA-256: `530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6` + +Sources: `packages/core/session/src/types.ts` + +One of: + +- `"change"` +- `"initial"` +- `"resume"` +- `"series"` + + + +#### `packages/core/session/src/types.ts#SessionHeader` + +SHA-256: `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `agentPreset` | optional | `string` | +| `createdAt` | required | `number` | +| `cwd` | optional | `string` | +| `delegationDepth` | optional | `number` | +| `id` | required | `string` | +| `isSeeded` | required | `boolean` | +| `origin` | optional | `"subagent"` | +| `parentSession` | optional | `string` | +| `version` | required | `3` | + + + +#### `packages/core/session/src/types.ts#SurfaceOp` + +SHA-256: `335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5` + +Sources: `packages/core/session/src/types.ts` + +One of: + +- `"append"` +- [`SessionEventEnvelope[6].surfaceOp[1]`](#persistence-type-sessioneventenvelope6surfaceop1) + + + +#### `packages/core/session/src/types.ts#TurnEndCancelCause` + +SHA-256: `1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0` + +Sources: `packages/core/session/src/types.ts` + +One of: + +- [`event:turn/end.data.reason[1].reason[2]`](#persistence-type-eventturnenddatareason1reason2) +- [`event:turn/end.data.reason[1].reason[3]`](#persistence-type-eventturnenddatareason1reason3) +- [`event:turn/end.data.reason[1].reason[4]`](#persistence-type-eventturnenddatareason1reason4) +- [`event:turn/end.data.reason[1].reason[1]`](#persistence-type-eventturnenddatareason1reason1) +- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) + + + +#### `packages/core/session/src/types.ts#TurnEndReason` + +SHA-256: `a5a8c15f08af1b0f26f40906e0797b6b0920fd01069e660becce35ab7fc48d77` + +Sources: `packages/core/session/src/types.ts` + +One of: + +- [`event:turn/end.data.reason[5]`](#persistence-type-eventturnenddatareason5) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) +- [`event:turn/end.data.reason[3]`](#persistence-type-eventturnenddatareason3) +- [`event:turn/end.data.reason[1]`](#persistence-type-eventturnenddatareason1) +- [`event:turn/end.data.reason[2]`](#persistence-type-eventturnenddatareason2) +- [`event:turn/end.data.reason[0]`](#persistence-type-eventturnenddatareason0) + + + +#### `packages/core/tools/src/index.ts#ToolRestriction` + +SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f` + +Sources: `packages/core/tools/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `allow` | optional | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `deny` | optional | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | + + + +#### `packages/core/tools/src/types.ts#PtcDispatchEventData` + +SHA-256: `8d2e5a3c4230e6ea6c0b5151f02241d0db02cd2551f2df1b6b9700cddcc0dca3` + +Sources: `packages/core/tools/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `unknown` (opaque) | +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `error` | optional | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | +| `isError` | required | `boolean` | +| `name` | required | `string` | +| `parentCallId` | required | `string` | +| `rootCallId` | required | `string` | +| `subCallId` | required | `string` | + + + +#### `packages/core/tools/src/types.ts#PtcDispatchStartEventData` + +SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f` + +Sources: `packages/core/tools/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `unknown` (opaque) | +| `name` | required | `string` | +| `parentCallId` | required | `string` | +| `rootCallId` | required | `string` | +| `subCallId` | required | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMemberPhase` + +SHA-256: `dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd` + +Sources: `packages/experimental/agent-team/src/types.ts` + +One of: + +- `"active"` +- `"failed"` +- `"provisioning"` + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot` + +SHA-256: `6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `context` | required | [`event:team/member.data.member.context`](#persistence-type-eventteammemberdatamembercontext) | +| `description` | required | `string` | +| `error` | optional | `string` | +| `id` | required | `string` | +| `name` | required | `string` | +| `phase` | required | [`packages/experimental/agent-team/src/types.ts#TeamMemberPhase`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammemberphase) | +| `provider` | required | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot` + +SHA-256: `5b694f394d5e11609887a3ccfa82844935d49806c37e336b30be2186d649ab94` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | required | `string` | +| `senderId` | required | `string` | +| `senderName` | required | `string` | +| `targetId` | required | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMessageSource` + +SHA-256: `2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"team-message"` | +| `messageId` | required | `string` | +| `senderId` | required | `string` | +| `senderName` | required | `string` | +| `teamId` | required | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot` + +SHA-256: `51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357` + +Sources: `packages/experimental/agent-team/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `blockedBy` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `description` | required | `string` | +| `id` | required | `string` | +| `ownerId` | optional | `string` | +| `revision` | required | `number` | +| `status` | required | [`packages/experimental/agent-team/src/types.ts#TeamTaskStatus`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtaskstatus) | +| `subject` | required | `string` | +| `writeScopes` | required | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamTaskStatus` + +SHA-256: `b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943` + +Sources: `packages/experimental/agent-team/src/types.ts` + +One of: + +- `"completed"` +- `"deleted"` +- `"in_progress"` +- `"pending"` + + + +#### `packages/feedback/command-feedback/src/types.ts#FeedbackRecord` + +SHA-256: `7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344` + +Sources: `packages/feedback/command-feedback/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `category` | optional | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | +| `text` | optional | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete` + +SHA-256: `7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06` + +Sources: `packages/feedback/message-feedback/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `messageId` | required | `string` | +| `sessionId` | required | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem` + +SHA-256: `3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182` + +Sources: `packages/feedback/message-feedback/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `category` | optional | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | +| `createdAt` | required | `number` | +| `messageId` | required | `string` | +| `note` | optional | `string` | +| `rating` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackrating) | +| `updatedAt` | required | `number` | +| `version` | required | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut` + +SHA-256: `aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626` + +Sources: `packages/feedback/message-feedback/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `item` | required | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackitem) | +| `sessionId` | required | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating` + +SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2` + +Sources: `packages/feedback/message-feedback/src/types.ts` + +One of: + +- `"negative"` +- `"positive"` + + + +#### `packages/fs/tool-present/src/types.ts#PresentedFile` + +SHA-256: `b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97` + +Sources: `packages/fs/tool-present/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `description` | optional | `string` | +| `path` | required | `string` | + + + +#### `packages/goal/goal/src/domain.ts#GoalChangeMeta` + +SHA-256: `7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438` + +Sources: `packages/goal/goal/src/domain.ts` + +One of: + +- [`packages/goal/goal/src/domain.ts#GoalClearChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalclearchangemeta) +- [`packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalsnapshotchangemeta) + + + +#### `packages/goal/goal/src/domain.ts#GoalClearChangeMeta` + +SHA-256: `cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f` + +Sources: `packages/goal/goal/src/domain.ts` + +| Property | Presence | Type | +|---|---|---| +| `cleared` | required | [`packages/goal/goal/src/types.ts#GoalRef`](#persistence-type-packagesgoalgoalsrctypestsgoalref) | +| `clearedAt` | required | `number` | +| `kind` | required | `"goal/change"` | +| `operation` | required | `"clear"` | +| `version` | required | `1` | + + + +#### `packages/goal/goal/src/domain.ts#GoalMessageSource` + +SHA-256: `7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc` + +Sources: `packages/goal/goal/src/domain.ts` + +| Property | Presence | Type | +|---|---|---| +| `goalId` | required | `string` | +| `kind` | required | `"goal"` | +| `revision` | required | `number` | +| `round` | required | `number` | + + + +#### `packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta` + +SHA-256: `1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4` + +Sources: `packages/goal/goal/src/domain.ts` + +| Property | Presence | Type | +|---|---|---| +| `createdAt` | required | `number` | +| `goal` | required | [`packages/goal/goal/src/types.ts#GoalSnapshot`](#persistence-type-packagesgoalgoalsrctypestsgoalsnapshot) | +| `kind` | required | `"goal/change"` | +| `operation` | required | [`event:goal/change.data[0].operation`](#persistence-type-eventgoalchangedata0operation) | +| `roundsStarted` | required | `number` | +| `updatedAt` | required | `number` | +| `version` | required | `1` | + + + +#### `packages/goal/goal/src/types.ts#GoalBlockReason` + +SHA-256: `84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c` + +Sources: `packages/goal/goal/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `code` | required | `string` | +| `message` | required | `string` | + + + +#### `packages/goal/goal/src/types.ts#GoalPhase` + +SHA-256: `b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172` + +Sources: `packages/goal/goal/src/types.ts` + +One of: + +- `"active"` +- `"blocked"` +- `"complete"` +- `"paused"` + + + +#### `packages/goal/goal/src/types.ts#GoalRef` + +SHA-256: `0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f` + +Sources: `packages/goal/goal/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `revision` | required | `number` | + + + +#### `packages/goal/goal/src/types.ts#GoalSnapshot` + +SHA-256: `6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25` + +Sources: `packages/goal/goal/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `blockedReason` | optional | [`packages/goal/goal/src/types.ts#GoalBlockReason`](#persistence-type-packagesgoalgoalsrctypestsgoalblockreason) | +| `id` | required | `string` | +| `maxGoalRounds` | required | `number` | +| `objective` | required | `string` | +| `phase` | required | [`packages/goal/goal/src/types.ts#GoalPhase`](#persistence-type-packagesgoalgoalsrctypestsgoalphase) | +| `revision` | required | `number` | + + + +#### `packages/hooks/hook-protocol/src/types.ts#HookDialect` + +SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` + +Sources: `packages/hooks/hook-protocol/src/types.ts` + +One of: + +- `"claude-code"` +- `"codex"` + + + +#### `packages/interaction/user-approval/src/index.ts#ApprovalPolicy` + +SHA-256: `05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf` + +Sources: `packages/interaction/user-approval/src/index.ts` + +One of: + +- `"ask"` +- `"never"` + + + +#### `packages/interaction/user-approval/src/types.ts#ApprovalOutcome` + +SHA-256: `930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7` + +Sources: `packages/interaction/user-approval/src/types.ts` + +One of: + +- `"allowed-once"` +- `"cancelled"` +- `"rejected"` +- `"unavailable"` + + + +#### `packages/llm/llm-retry/src/types.ts#LlmRetryEventData` + +SHA-256: `c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1` + +Sources: `packages/llm/llm-retry/src/types.ts` + +One of: + +- [`event:llm/retry.data[0]`](#persistence-type-eventllmretrydata0) +- [`event:llm/retry.data[1]`](#persistence-type-eventllmretrydata1) + + + +#### `packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData` + +SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20` + +Sources: `packages/llm/llm-retry/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `retry` | required | `number` | +| `retryId` | required | `string` | +| `step` | required | `number` | +| `turn` | required | `number` | + + + +#### `packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord` + +SHA-256: `86cf1e44038cb8b11659863dd0efafe682e41b9c782265c1d50e0a687debfc60` + +Sources: `packages/llm/llm/src/assistant-stream.ts` + +One of: + +- [`event:assistant/attempt.data.stream[0][2]`](#persistence-type-eventassistantattemptdatastream02) +- [`event:assistant/attempt.data.stream[0][3]`](#persistence-type-eventassistantattemptdatastream03) +- [`event:assistant/attempt.data.stream[0][1]`](#persistence-type-eventassistantattemptdatastream01) +- [`event:assistant/attempt.data.stream[0][0]`](#persistence-type-eventassistantattemptdatastream00) + + + +#### `packages/llm/llm/src/call-config.ts#LlmCallConfig` + +SHA-256: `67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0` + +Sources: `packages/llm/llm/src/call-config.ts` + +| Property | Presence | Type | +|---|---|---| +| `maxTokens` | optional | `number` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `reasoningEffort` | optional | `string` | +| `stop` | optional | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `temperature` | optional | `number` | + + + +#### `packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults` + +SHA-256: `326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693` + +Sources: `packages/llm/llm/src/call-config.ts` + +| Property | Presence | Type | +|---|---|---| +| `maxTokens` | optional | `true` | +| `reasoningEffort` | optional | `true` | + + + +#### `packages/llm/llm/src/message.ts#AssistantMessage` + +SHA-256: `e50b0a3ed8e6c80b672e4f855c91984f03b5c3fdd5d475bf171171f391a86c83` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | required | `string` | +| `role` | required | `"assistant"` | +| `source` | required | [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) | + + + +#### `packages/llm/llm/src/message.ts#ContextSnapshotSection` + +SHA-256: `86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `name` | required | `string` | +| `text` | required | `string` | + + + +#### `packages/llm/llm/src/message.ts#Message` + +SHA-256: `23c7cce57d20589897f4e2bd5898affc6fc611b87cd0cc8b95be1cfdd8b3a7eb` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | required | `string` | +| `role` | required | [`event:session/title-llm-request.data.messages[0].role`](#persistence-type-eventsessiontitle-llm-requestdatamessages0role) | +| `source` | required | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | + + + +#### `packages/llm/llm/src/message.ts#MessageSource` + +SHA-256: `4c965666d5b42116945bc356087cd5e1fd549e6dece560785ed60511059a8283` + +Sources: `packages/llm/llm/src/message.ts` + +One of: + +- [`packages/context/agent-instructions/src/state.ts#AgentInstructionSource`](#persistence-type-packagescontextagent-instructionssrcstatetsagentinstructionsource) +- [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) +- [`event:agent/inbox/spliced.data.inserted[0].source[10]`](#persistence-type-eventagentinboxspliceddatainserted0source10) +- [`event:agent/inbox/spliced.data.inserted[0].source[19]`](#persistence-type-eventagentinboxspliceddatainserted0source19) +- [`packages/skill/tool-skill/src/index.ts#SkillCatalogSource`](#persistence-type-packagesskilltool-skillsrcindextsskillcatalogsource) +- [`packages/skill/skill/src/index.ts#SkillInvocationSource`](#persistence-type-packagesskillskillsrcindextsskillinvocationsource) +- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) +- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) +- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) +- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) +- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) +- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) +- [`packages/context/session-reference/src/types.ts#SessionReferenceSource`](#persistence-type-packagescontextsession-referencesrctypestssessionreferencesource) +- [`packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestssubagentsettledmessagesource) +- [`packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestsagentmessagesource) +- [`packages/goal/goal/src/domain.ts#GoalMessageSource`](#persistence-type-packagesgoalgoalsrcdomaintsgoalmessagesource) +- [`packages/experimental/agent-team/src/types.ts#TeamMessageSource`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesource) +- [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) +- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) +- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) + + + +#### `packages/llm/llm/src/message.ts#ModelMessageSource` + +SHA-256: `719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `kind` | required | `"model"` | +| `model` | required | `string` | +| `provider` | required | `string` | +| `replayState` | optional | `unknown` (opaque) | + + + +#### `packages/llm/llm/src/message.ts#SystemMessage` + +SHA-256: `302b01ddddcbb3b16cfa3fba2a5d99f5082a55fbd9dc5c83a179a228b8a6a0ca` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | required | `string` | +| `role` | required | `"system"` | +| `source` | required | [`event:system/message.data.message.source`](#persistence-type-eventsystemmessagedatamessagesource) | + + + +#### `packages/llm/llm/src/message.ts#ToolMessageSource` + +SHA-256: `d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `callId` | required | `string` | +| `kind` | required | `"tool"` | + + + +#### `packages/llm/llm/src/message.ts#ToolResultMessage` + +SHA-256: `1b573e2d5c094fa87e2a8bf409ddd4ac5ba92a123085e168de44b9ccdbd5244c` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:tool/result.data.message.content`](#persistence-type-eventtoolresultdatamessagecontent) | +| `id` | required | `string` | +| `role` | required | `"user"` | +| `source` | required | [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) | + + + +#### `packages/llm/llm/src/message.ts#UserMessage` + +SHA-256: `4de5e7644130ed715ef6b5a4d86a87b30dca4096d1a6683c66acf6f7809379c7` + +Sources: `packages/llm/llm/src/message.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | required | `string` | +| `role` | required | `"user"` | +| `source` | required | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | + + + +#### `packages/llm/llm/src/types.ts#ContentBlock` + +SHA-256: `c7b24be059d34d08929593049a1a81eaa3855166aacfe9d7603c0bc8bb728d56` + +Sources: `packages/llm/llm/src/types.ts` + +One of: + +- [`packages/llm/llm/src/types.ts#ReasoningBlock`](#persistence-type-packagesllmllmsrctypestsreasoningblock) +- [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) +- [`packages/llm/llm/src/types.ts#ToolCallBlock`](#persistence-type-packagesllmllmsrctypeststoolcallblock) +- [`packages/llm/llm/src/types.ts#ImageBlock`](#persistence-type-packagesllmllmsrctypestsimageblock) +- [`packages/llm/llm/src/types.ts#FileBlock`](#persistence-type-packagesllmllmsrctypestsfileblock) +- [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) + + + +#### `packages/llm/llm/src/types.ts#ContentBlockType` + +SHA-256: `757013fff5879d73d5753d8d1120faab56110e88ac3932485ab7e034d9e9ce61` + +Sources: `packages/llm/llm/src/types.ts` + +One of: + +- `"file"` +- `"image"` +- `"reasoning"` +- `"text"` +- `"tool-call"` +- `"tool-result"` + + + +#### `packages/llm/llm/src/types.ts#FileBlock` + +SHA-256: `f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `attachment` | required | [`packages/attachment/attachment/src/types.ts#FileAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsfileattachmentref) | +| `type` | required | `"file"` | + + + +#### `packages/llm/llm/src/types.ts#FinishReason` + +SHA-256: `5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80` + +Sources: `packages/llm/llm/src/types.ts` + +One of: + +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]`](#persistence-type-eventassistantattemptdatastream03chunk6reason3) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]`](#persistence-type-eventassistantattemptdatastream03chunk6reason4) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]`](#persistence-type-eventassistantattemptdatastream03chunk6reason0) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]`](#persistence-type-eventassistantattemptdatastream03chunk6reason1) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) + + + +#### `packages/llm/llm/src/types.ts#ImageBlock` + +SHA-256: `12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `attachment` | required | [`packages/attachment/attachment/src/types.ts#ImageAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsimageattachmentref) | +| `offloaded` | optional | `true` | +| `type` | required | `"image"` | + + + +#### `packages/llm/llm/src/types.ts#LlmFailure` + +SHA-256: `5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `code` | required | `string` | +| `message` | required | `string` | +| `offloadImages` | optional | `number` | +| `providerRetryAfterMs` | optional | `number` | +| `requestId` | optional | `string` | +| `status` | optional | `number` | + + + +#### `packages/llm/llm/src/types.ts#ReasoningBlock` + +SHA-256: `814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `text` | required | `string` | +| `type` | required | `"reasoning"` | + + + +#### `packages/llm/llm/src/types.ts#ReplayEnvelope` + +SHA-256: `0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `blocks` | optional | [`event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks`](#persistence-type-eventassistantattemptdatastream03chunk6replaystateblocks) | +| `response` | required | `unknown` (opaque) | + + + +#### `packages/llm/llm/src/types.ts#StreamChunk` + +SHA-256: `071d92b9dac661fcc826c678cf64d188f26fb93aab79c627b11a03acdd34dfca` + +Sources: `packages/llm/llm/src/types.ts` + +One of: + +- [`event:assistant/attempt.data.stream[0][3].chunk[3]`](#persistence-type-eventassistantattemptdatastream03chunk3) +- [`event:assistant/attempt.data.stream[0][3].chunk[4]`](#persistence-type-eventassistantattemptdatastream03chunk4) +- [`event:assistant/attempt.data.stream[0][3].chunk[0]`](#persistence-type-eventassistantattemptdatastream03chunk0) +- [`event:assistant/attempt.data.stream[0][3].chunk[2]`](#persistence-type-eventassistantattemptdatastream03chunk2) +- [`event:assistant/attempt.data.stream[0][3].chunk[1]`](#persistence-type-eventassistantattemptdatastream03chunk1) +- [`event:assistant/attempt.data.stream[0][3].chunk[6]`](#persistence-type-eventassistantattemptdatastream03chunk6) +- [`event:assistant/attempt.data.stream[0][3].chunk[5]`](#persistence-type-eventassistantattemptdatastream03chunk5) + + + +#### `packages/llm/llm/src/types.ts#TokenUsage` + +SHA-256: `fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `cacheReadTokens` | optional | `number` | +| `cacheWriteTokens` | optional | `number` | +| `inputTokens` | required | `number` | +| `outputTokens` | required | `number` | +| `reasoningTokens` | optional | `number` | +| `totalTokens` | optional | `number` | + + + +#### `packages/llm/llm/src/types.ts#ToolCallBlock` + +SHA-256: `c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `arguments` | required | `string` | +| `id` | required | `string` | +| `name` | required | `string` | +| `type` | required | `"tool-call"` | + + + +#### `packages/llm/llm/src/types.ts#ToolResultBlock` + +SHA-256: `d61574d68558c5a184429e70b04da393dd5460bf5cc3ddef814546e659bd5127` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `isError` | optional | `boolean` | +| `toolCallId` | required | `string` | +| `type` | required | `"tool-result"` | + + + +#### `packages/llm/llm/src/types.ts#ToolSchema` + +SHA-256: `7f5f2a8618c2ece530a18b1358b890fb57fb8c35705e47b66bff2296f8c6e889` + +Sources: `packages/llm/llm/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `description` | required | `string` | +| `name` | required | `string` | +| `parameters` | required | [`event:request/header.data.header.tools[0].parameters`](#persistence-type-eventrequestheaderdataheadertools0parameters) | + + + +#### `packages/sandbox/sandbox/src/index.ts#SandboxMode` + +SHA-256: `fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd` + +Sources: `packages/sandbox/sandbox/src/index.ts` + +One of: + +- `"danger-full-access"` +- `"read-only"` +- `"workspace-write"` + + + +#### `packages/schedule/schedule/src/types.ts#AfterScheduleRecord` + +SHA-256: `27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `afterSeconds` | required | `number` | +| `id` | required | `string` | +| `kind` | required | `"after"` | +| `prompt` | required | `string` | +| `scheduledAt` | required | `string` | + + + +#### `packages/schedule/schedule/src/types.ts#AtScheduleRecord` + +SHA-256: `658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `kind` | required | `"at"` | +| `prompt` | required | `string` | +| `scheduledAt` | required | `string` | + + + +#### `packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange` + +SHA-256: `e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `acceptedAt` | required | `string` | +| `id` | required | `string` | +| `operation` | required | `"dispatch"` | +| `version` | required | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#EveryScheduleRecord` + +SHA-256: `66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `everySeconds` | required | `number` | +| `id` | required | `string` | +| `kind` | required | `"every"` | +| `prompt` | required | `string` | +| `scheduledAt` | required | `string` | + + + +#### `packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange` + +SHA-256: `8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `operation` | required | `"dispatch"` | +| `version` | required | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleChange` + +SHA-256: `e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1` + +Sources: `packages/schedule/schedule/src/types.ts` + +One of: + +- [`packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestseveryscheduledispatchchange) +- [`packages/schedule/schedule/src/types.ts#ScheduleDeleteChange`](#persistence-type-packagesscheduleschedulesrctypestsscheduledeletechange) +- [`packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestsoneshotscheduledispatchchange) +- [`packages/schedule/schedule/src/types.ts#ScheduleCreateChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulecreatechange) + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleCreateChange` + +SHA-256: `ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `operation` | required | `"create"` | +| `schedule` | required | [`packages/schedule/schedule/src/types.ts#ScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsschedulerecord) | +| `version` | required | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleDeleteChange` + +SHA-256: `18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0` + +Sources: `packages/schedule/schedule/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `id` | required | `string` | +| `operation` | required | `"delete"` | +| `version` | required | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleRecord` + +SHA-256: `d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87` + +Sources: `packages/schedule/schedule/src/types.ts` + +One of: + +- [`packages/schedule/schedule/src/types.ts#AfterScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsafterschedulerecord) +- [`packages/schedule/schedule/src/types.ts#EveryScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestseveryschedulerecord) +- [`packages/schedule/schedule/src/types.ts#AtScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsatschedulerecord) + + + +#### `packages/session/session-persistence-jsonl/src/format.ts#HeaderLine` + +SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` + +Sources: `packages/session/session-persistence-jsonl/src/format.ts` + +| Property | Presence | Type | +|---|---|---| +| `agentPreset` | optional | `string` | +| `createdAt` | required | `number` | +| `cwd` | optional | `string` | +| `delegationDepth` | required | `number` | +| `id` | required | `string` | +| `isSeeded` | required | `boolean` | +| `origin` | optional | `"subagent"` | +| `parentSession` | optional | `string` | +| `type` | required | `"session"` | +| `version` | required | `number` | + + + +#### `packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData` + +SHA-256: `9fe0e77a7816b7fdb4b953ec0e2f0cd7bbd22c5de5c3567e612d1b20eb0992e6` + +Sources: `packages/session/session-title-llm/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `maxTokens` | required | `number` | +| `messageSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `messages` | required | [`event:session/title-llm-request.data.messages`](#persistence-type-eventsessiontitle-llm-requestdatamessages) | +| `route` | required | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | +| `system` | required | `string` | +| `titleProvider` | required | `string` | + + + +#### `packages/session/session-title/src/types.ts#SessionTitleEventData` + +SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4` + +Sources: `packages/session/session-title/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `messageSeqs` | required | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `source` | required | [`packages/session/session-title/src/types.ts#SessionTitleSource`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlesource) | +| `title` | required | `string` | + + + +#### `packages/session/session-title/src/types.ts#SessionTitleModelIdentity` + +SHA-256: `07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235` + +Sources: `packages/session/session-title/src/types.ts` · `packages/subagent/tool-subagent/src/model-selection.ts` + +| Property | Presence | Type | +|---|---|---| +| `model` | required | `string` | +| `provider` | required | `string` | + + + +#### `packages/session/session-title/src/types.ts#SessionTitleSource` + +SHA-256: `30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f` + +Sources: `packages/session/session-title/src/types.ts` + +One of: + +- [`event:session/title.data.source[1]`](#persistence-type-eventsessiontitledatasource1) +- [`event:session/title.data.source[0]`](#persistence-type-eventsessiontitledatasource0) +- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) + + + +#### `packages/skill/skill/src/index.ts#SkillInvocationSource` + +SHA-256: `672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db` + +Sources: `packages/skill/skill/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"instructions"` | +| `kind` | required | `"skill-invocation"` | +| `name` | required | `string` | + + + +#### `packages/skill/tool-skill/src/index.ts#SkillCatalogSource` + +SHA-256: `fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093` + +Sources: `packages/skill/tool-skill/src/index.ts` + +| Property | Presence | Type | +|---|---|---| +| `entries` | required | [`event:agent/inbox/spliced.data.inserted[0].source[17].entries`](#persistence-type-eventagentinboxspliceddatainserted0source17entries) | +| `form` | required | `"catalog"` | +| `kind` | required | `"skill-catalog"` | +| `update` | optional | `true` | + + + +#### `packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent` + +SHA-256: `3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e` + +Sources: `packages/subagent/subagent/src/catalog.ts` + +One of: + +- [`event:subagent/catalog.data[1]`](#persistence-type-eventsubagentcatalogdata1) +- [`event:subagent/catalog.data[0]`](#persistence-type-eventsubagentcatalogdata0) + + + +#### `packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource` + +SHA-256: `4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86` + +Sources: `packages/subagent/subagent/src/continuation-messages.ts` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"relay"` | +| `kind` | required | `"agent-message"` | +| `senderSessionId` | required | `string` | + + + +#### `packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource` + +SHA-256: `4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a` + +Sources: `packages/subagent/subagent/src/continuation-messages.ts` + +| Property | Presence | Type | +|---|---|---| +| `form` | required | `"notice"` | +| `kind` | required | `"subagent-settled"` | +| `senderSessionId` | required | `string` | +| `summary` | required | `string` | + + + +#### `packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData` + +SHA-256: `6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f` + +Sources: `packages/subagent/subagent/src/descriptor.ts` + +| Property | Presence | Type | +|---|---|---| +| `agentModel` | optional | `string` | +| `agentProvider` | optional | `string` | +| `agentReasoningEffort` | optional | `string` | +| `label` | required | `string` | +| `mode` | required | `"continuable"` | +| `persona` | optional | `string` | +| `provider` | required | `string` | +| `toolFilter` | optional | [`packages/core/tools/src/index.ts#ToolRestriction`](#persistence-type-packagescoretoolssrcindextstoolrestriction) | +| `version` | required | `number` | + + + +#### `packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData` + +SHA-256: `5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564` + +Sources: `packages/subagent/subagent/src/descriptor.ts` + +| Property | Presence | Type | +|---|---|---| +| `label` | optional | `string` | +| `mode` | required | `"one-shot"` | +| `provider` | required | `string` | +| `version` | required | `number` | + + + +#### `packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData` + +SHA-256: `86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde` + +Sources: `packages/subagent/subagent/src/descriptor.ts` + +One of: + +- [`packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortscontinuablesubagentdescriptordata) +- [`packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortsoneshotsubagentdescriptordata) + + + +#### `packages/todo/tool-todo/src/types.ts#TodoItem` + +SHA-256: `a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a` + +Sources: `packages/todo/tool-todo/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `content` | required | `string` | +| `status` | required | [`event:todo/write.data.todos[0].status`](#persistence-type-eventtodowritedatatodos0status) | + + + +#### `packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest` + +SHA-256: `2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9` + +Sources: `packages/web/web-search-deepseek/src/provider.ts` + +| Property | Presence | Type | +|---|---|---| +| `apiVersion` | required | `string` | +| `body` | required | [`event:web/deepseek-search-llm-request.data.body`](#persistence-type-eventwebdeepseek-search-llm-requestdatabody) | +| `endpoint` | required | `string` | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData` + +SHA-256: `c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7` + +Sources: `packages/workflow/tool-workflow/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `outcome` | required | [`packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowagentoutcome) | +| `runId` | required | `string` | +| `seq` | required | `number` | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData` + +SHA-256: `9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc` + +Sources: `packages/workflow/tool-workflow/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `childId` | required | `string` | +| `label` | required | `string` | +| `phase` | optional | `string` | +| `runId` | required | `string` | +| `seq` | required | `number` | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData` + +SHA-256: `7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462` + +Sources: `packages/workflow/tool-workflow/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `runId` | required | `string` | +| `stopReason` | required | [`packages/workflow/workflow/src/types.ts#WorkflowStopReason`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowstopreason) | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData` + +SHA-256: `a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c` + +Sources: `packages/workflow/tool-workflow/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `name` | required | `string` | +| `runId` | required | `string` | + + + +#### `packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome` + +SHA-256: `c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896` + +Sources: `packages/workflow/workflow/src/types.ts` + +One of: + +- `"cancelled"` +- `"completed"` +- `"failed"` + + + +#### `packages/workflow/workflow/src/types.ts#WorkflowStopReason` + +SHA-256: `8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15` + +Sources: `packages/workflow/workflow/src/types.ts` + +One of: + +- `"cancelled"` +- `"completed"` +- `"error"` + + + +#### `"parent"` + +SHA-256: `e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732` + +`"parent"` + + + +#### `"pause"` + +SHA-256: `1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721` + +`"pause"` + + + +#### `"paused"` + +SHA-256: `c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943` + +`"paused"` + + + +#### `"pending"` + +SHA-256: `234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85` + +`"pending"` + + + +#### `"permission/preset"` + +SHA-256: `ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649` + +`"permission/preset"` + + + +#### `"plan/mode"` + +SHA-256: `f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9` + +`"plan/mode"` + + + +#### `"plugin"` + +SHA-256: `e654d28d1e6c471147310d2fba396d00969cfe6ed9022626d3f2c2312e0b1cbb` + +`"plugin"` + + + +#### `"positive"` + +SHA-256: `df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528` + +`"positive"` + + + +#### `"product-interaction"` + +SHA-256: `0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23` + +`"product-interaction"` + + + +#### `"provider"` + +SHA-256: `e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a` + +`"provider"` + + + +#### `"provisioning"` + +SHA-256: `871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62` + +`"provisioning"` + + + +#### `"read-only"` + +SHA-256: `12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42` + +`"read-only"` + + + +#### `"reasoning"` + +SHA-256: `3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c` + +`"reasoning"` + + + +#### `"reasoning-chunks"` + +SHA-256: `688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8` + +`"reasoning-chunks"` + + + +#### `"reasoning-delta"` + +SHA-256: `6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6` + +`"reasoning-delta"` + + + +#### `"recall"` + +SHA-256: `383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f` + +`"recall"` + + + +#### `"rejected"` + +SHA-256: `fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018` + +`"rejected"` + + + +#### `"relay"` + +SHA-256: `16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e` + +`"relay"` + + + +#### `"remove"` + +SHA-256: `7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc` + +`"remove"` + + + +#### `"replace"` + +SHA-256: `f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8` + +`"replace"` + + + +#### `"request/context"` + +SHA-256: `70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2` + +`"request/context"` + + + +#### `"request/header"` + +SHA-256: `3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e` + +`"request/header"` + + + +#### `"resource-cost"` + +SHA-256: `5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75` + +`"resource-cost"` + + + +#### `"resume"` + +SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66` + +`"resume"` + + + +#### `"sandbox/mode"` + +SHA-256: `ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2` + +`"sandbox/mode"` + + + +#### `"schedule/change"` + +SHA-256: `0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d` + +`"schedule/change"` + + + +#### `"security-privacy-permission"` + +SHA-256: `07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7` + +`"security-privacy-permission"` + + + +#### `"series"` + +SHA-256: `4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f` + +`"series"` + + + +#### `"service-stability"` + +SHA-256: `7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732` + +`"service-stability"` + + + +#### `"session"` + +SHA-256: `e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828` + +`"session"` + + + +#### `"session-log-deepseek/delivery-accepted"` + +SHA-256: `47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b` + +`"session-log-deepseek/delivery-accepted"` + + + +#### `"session-reference"` + +SHA-256: `7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71` + +`"session-reference"` + + + +#### `"session/end-seed"` + +SHA-256: `1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330` + +`"session/end-seed"` + + + +#### `SessionEventEnvelope` + +SHA-256: `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` + +One of: + +- [`SessionEventEnvelope[39]`](#persistence-type-sessioneventenvelope39) +- [`SessionEventEnvelope[6]`](#persistence-type-sessioneventenvelope6) +- [`SessionEventEnvelope[0]`](#persistence-type-sessioneventenvelope0) + + + +#### `SessionEventEnvelope[0]` + +SHA-256: `e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f` + +| Property | Presence | Type | +|---|---|---| +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `time` | required | `number` | +| `type` | required | `string` | + + + +#### `SessionEventEnvelope[39]` + +SHA-256: `998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0` + +| Property | Presence | Type | +|---|---|---| +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `sourceEventSeqs` | optional | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | required | `number` | +| `type` | required | `string` | + + + +#### `SessionEventEnvelope[39].sourceEventSeqs` + +SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` + +Array of `number`. + + + +#### `SessionEventEnvelope[6]` + +SHA-256: `7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb` + +| Property | Presence | Type | +|---|---|---| +| `ignorable` | optional | `true` | +| `seq` | required | `number` | +| `surfaceOp` | required | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | required | `number` | +| `type` | required | `string` | + + + +#### `SessionEventEnvelope[6].surfaceOp[1]` + +SHA-256: `bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825` + +Sources: `packages/core/session/src/types.ts` + +| Property | Presence | Type | +|---|---|---| +| `endSeq` | required | `number` | +| `op` | required | `"replace"` | +| `startSeq` | required | `number` | + + + +#### `"session/title"` + +SHA-256: `7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50` + +`"session/title"` + + + +#### `"session/title-llm-request"` + +SHA-256: `587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e` + +`"session/title-llm-request"` + + + +#### `"set"` + +SHA-256: `b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b` + +`"set"` + + + +#### `"skill-catalog"` + +SHA-256: `6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3` + +`"skill-catalog"` + + + +#### `"skill-invocation"` + +SHA-256: `1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509` + +`"skill-invocation"` + + + +#### `"snapshot"` + +SHA-256: `6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912` + +`"snapshot"` + + + +#### `"step/end"` + +SHA-256: `c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70` + +`"step/end"` + + + +#### `"step/start"` + +SHA-256: `2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d` + +`"step/start"` + + + +#### `"stop"` + +SHA-256: `57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90` + +`"stop"` + + + +#### `string` + +SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` + +Sources: `packages/api/session-controller/src/types.ts` · `packages/attachment/attachment/src/brand.ts` · `packages/compaction/compaction/src/brand.ts` · `packages/core/session/src/types.ts` · `packages/experimental/agent-team/src/types.ts` · `packages/feedback/message-feedback/src/types.ts` · `packages/goal/goal/src/types.ts` · `packages/interaction/commands/src/brand.ts` · `packages/interaction/user-approval/src/types.ts` · `packages/llm/llm-retry/src/brand.ts` · `packages/llm/llm/src/brand.ts` · `packages/schedule/schedule/src/types.ts` · `packages/session/session-title/src/index.ts` · `packages/session/session-title/src/types.ts` · `packages/webhook/webhook/src/brand.ts` · `packages/workflow/workflow/src/types.ts` + +`string` + + + +#### `"subagent"` + +SHA-256: `aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6` + +`"subagent"` + + + +#### `"subagent-settled"` + +SHA-256: `bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a` + +`"subagent-settled"` + + + +#### `"subagent/catalog"` + +SHA-256: `44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2` + +`"subagent/catalog"` + + + +#### `"subagent/descriptor"` + +SHA-256: `5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647` + +`"subagent/descriptor"` + + + +#### `"subagent/model-selection-policy"` + +SHA-256: `0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da` + +`"subagent/model-selection-policy"` + + + +#### `"success"` + +SHA-256: `511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7` + +`"success"` + + + +#### `"system"` + +SHA-256: `8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3` + +`"system"` + + + +#### `"system/message"` + +SHA-256: `1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7` + +`"system/message"` + + + +#### `"task-result"` + +SHA-256: `f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c` + +`"task-result"` + + + +#### `"team-message"` + +SHA-256: `2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c` + +`"team-message"` + + + +#### `"team/member"` + +SHA-256: `18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0` + +`"team/member"` + + + +#### `"team/message/delivered"` + +SHA-256: `a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57` + +`"team/message/delivered"` + + + +#### `"team/message/queued"` + +SHA-256: `4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159` + +`"team/message/queued"` + + + +#### `"team/task"` + +SHA-256: `b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b` + +`"team/task"` + + + +#### `"text"` + +SHA-256: `4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d` + +`"text"` + + + +#### `"text-chunks"` + +SHA-256: `f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3` + +`"text-chunks"` + + + +#### `"text-delta"` + +SHA-256: `5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563` + +`"text-delta"` + + + +#### `"todo/write"` + +SHA-256: `af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7` + +`"todo/write"` + + + +#### `"tool"` + +SHA-256: `a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847` + +`"tool"` + + + +#### `"tool-call"` + +SHA-256: `1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7` + +`"tool-call"` + + + +#### `"tool-call-chunks"` + +SHA-256: `616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5` + +`"tool-call-chunks"` + + + +#### `"tool-call-delta"` + +SHA-256: `9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267` + +`"tool-call-delta"` + + + +#### `"tool-calls"` + +SHA-256: `6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b` + +`"tool-calls"` + + + +#### `"tool-result"` + +SHA-256: `e5244812c495a80c2e78ba2c2690dca5f6b58ea8d3fe5531ff94a6f9ac5e5d66` + +`"tool-result"` + + + +#### `"tool-workflow/agent-end"` + +SHA-256: `5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e` + +`"tool-workflow/agent-end"` + + + +#### `"tool-workflow/agent-start"` + +SHA-256: `ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8` + +`"tool-workflow/agent-start"` + + + +#### `"tool-workflow/run-end"` + +SHA-256: `fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd` + +`"tool-workflow/run-end"` + + + +#### `"tool-workflow/run-start"` + +SHA-256: `cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670` + +`"tool-workflow/run-start"` + + + +#### `"tool/call"` + +SHA-256: `c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92` + +`"tool/call"` + + + +#### `"tool/ptc-dispatch"` + +SHA-256: `fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973` + +`"tool/ptc-dispatch"` + + + +#### `"tool/ptc-dispatch-start"` + +SHA-256: `2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456` + +`"tool/ptc-dispatch-start"` + + + +#### `"tool/result"` + +SHA-256: `570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833` + +`"tool/result"` + + + +#### `true` + +SHA-256: `dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521` + +`true` + + + +#### `"turn/end"` + +SHA-256: `4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03` + +`"turn/end"` + + + +#### `"turn/start"` + +SHA-256: `0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f` + +`"turn/start"` + + + +#### `"unavailable"` + +SHA-256: `2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c` + +`"unavailable"` + + + +#### `unknown` + +SHA-256: `bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d` + +`unknown`: the declaration does not expose the stored value's internal fields. + + + +#### `"usage"` + +SHA-256: `0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9` + +`"usage"` + + + +#### `"user"` + +SHA-256: `68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573` + +`"user"` + + + +#### `"user/message"` + +SHA-256: `de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f` + +`"user/message"` + + + +#### `"web_search"` + +SHA-256: `935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682` + +`"web_search"` + + + +#### `"web_search_20250305"` + +SHA-256: `0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e` + +`"web_search_20250305"` + + + +#### `"web/deepseek-search-llm-request"` + +SHA-256: `6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675` + +`"web/deepseek-search-llm-request"` + + + +#### `"webhook"` + +SHA-256: `db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0` + +`"webhook"` + + + +#### `"workspace-write"` + +SHA-256: `a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa` + +`"workspace-write"` + +
+ + + + +## Verification and limitations + +`pnpm run verify-persistence-catalog` passed before `pnpm run verify-persistence-formats --archive 3` created the schema from the current V3 inventory. Archival retains every root and its reachable declared types, preserves root digests and opaque declarations, and removes source line numbers. Earlier format records remain unchanged. + +The inventory records declared fields and optionality, not every codec or restoration invariant. External plugin payloads, physical range encoding, and runtime relationships need their owning validators; schema completeness alone does not establish migration safety. + +```sh +pnpm run verify-persistence-formats +``` + +The check validates every format through the current writer, schema completeness, bilingual declarations, and generated tables using only this checkout. It does not replay historical applications. See the [format index](README.md) for maintenance rules and the [current catalog](../../persistence-catalog.md) for today's declarations. + + +## Dev Note + +None. diff --git a/docs/persistence-changes/historical-formats/v3.schema.json b/docs/persistence-changes/historical-formats/v3.schema.json new file mode 100644 index 0000000000..8667e6ae90 --- /dev/null +++ b/docs/persistence-changes/historical-formats/v3.schema.json @@ -0,0 +1,61307 @@ +{ + "formatVersion": 1, + "roots": [ + { + "key": "SessionHeader", + "kind": "header", + "digest": "2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 2, + "optional": false + }, + { + "name": "cwd", + "type": 1, + "optional": true + }, + { + "name": "delegationDepth", + "type": 2, + "optional": true + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "isSeeded", + "type": 3, + "optional": false + }, + { + "name": "origin", + "type": 4, + "optional": true + }, + { + "name": "parentSession", + "type": 1, + "optional": true + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "subagent" + }, + { + "kind": "literal", + "value": 3 + } + ] + } + }, + { + "key": "JsonlHeaderLine", + "kind": "header", + "digest": "18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 2, + "optional": false + }, + { + "name": "cwd", + "type": 1, + "optional": true + }, + { + "name": "delegationDepth", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "isSeeded", + "type": 3, + "optional": false + }, + { + "name": "origin", + "type": 4, + "optional": true + }, + { + "name": "parentSession", + "type": 1, + "optional": true + }, + { + "name": "type", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "subagent" + }, + { + "kind": "literal", + "value": "session" + } + ] + } + }, + { + "key": "SessionEventEnvelope", + "kind": "envelope", + "digest": "5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 10, + 11 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 4, + "optional": true + }, + { + "name": "surfaceOp", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 3, + "optional": false + }, + { + "name": "op", + "type": 8, + "optional": false + }, + { + "name": "startSeq", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "surfaceOp", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + } + ] + } + }, + { + "key": "event:agent-preset/selected", + "kind": "event", + "event": "agent-preset/selected", + "surface": false, + "digest": "a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "agent-preset/selected" + } + ] + } + }, + { + "key": "event:agent/inbox/spliced", + "kind": "event", + "event": "agent/inbox/spliced", + "surface": false, + "digest": "646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 18, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 90, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "inserted", + "type": 2, + "optional": false + }, + { + "name": "outcome", + "type": 86, + "optional": true + }, + { + "name": "removedCount", + "type": 11, + "optional": true + }, + { + "name": "start", + "type": 11, + "optional": false + }, + { + "name": "target", + "type": 87, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 20, + 23, + 26, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 18, + "optional": true + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 21, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 32, + 41, + 43, + 44, + 47, + 52, + 54, + 59, + 60, + 61, + 63, + 65, + 66, + 73, + 75, + 77, + 79, + 81, + 84, + 85 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 18, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 33, + "optional": false + }, + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 35, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 36, + 37, + 38 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 48, + "optional": false + }, + { + "name": "form", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "update", + "type": 18, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 49 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + }, + { + "name": "sections", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 58 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 64, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 67, + "optional": false + }, + { + "name": "references", + "type": 68, + "optional": false + }, + { + "name": "version", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 69 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 11, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 70, + "optional": false + }, + { + "name": "compacted", + "type": 24, + "optional": false + }, + { + "name": "inputIndex", + "type": 11, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 11, + "optional": false + }, + { + "name": "omittedMessages", + "type": 11, + "optional": false + }, + { + "name": "originalMessages", + "type": 11, + "optional": false + }, + { + "name": "retainedMessages", + "type": 11, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 11, + 71 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 64, + "optional": false + }, + { + "name": "kind", + "type": 76, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "revision", + "type": 11, + "optional": false + }, + { + "name": "round", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 82, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 83, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "canceled" + }, + { + "kind": "union", + "types": [ + 88, + 89 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + }, + { + "kind": "literal", + "value": "agent/inbox/spliced" + } + ] + } + }, + { + "key": "event:approval/asked", + "kind": "event", + "event": "approval/asked", + "surface": false, + "digest": "3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 2, + "optional": true + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 2, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "approval/asked" + } + ] + } + }, + { + "key": "event:approval/decided", + "kind": "event", + "event": "approval/decided", + "surface": false, + "digest": "bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 8, + "optional": true + }, + { + "name": "seq", + "type": 9, + "optional": false + }, + { + "name": "time", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "outcome", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "allowed-once" + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "rejected" + }, + { + "kind": "literal", + "value": "unavailable" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "approval/decided" + } + ] + } + }, + { + "key": "event:approval/policy", + "kind": "event", + "event": "approval/policy", + "surface": false, + "digest": "26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 7, + "optional": false + }, + { + "name": "time", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "policy", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "ask" + }, + { + "kind": "literal", + "value": "never" + }, + { + "kind": "literal", + "value": "delegation" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "approval/policy" + } + ] + } + }, + { + "key": "event:assistant/attempt", + "kind": "event", + "event": "assistant/attempt", + "surface": false, + "digest": "c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "stream", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 10, + 68, + 70 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 6, + "optional": false + }, + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 12, + 14, + 40, + 43, + 45, + 47, + 64 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 15, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 16, + 18, + 28, + 31, + 35, + 37 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 32, + "optional": false + }, + { + "name": "isError", + "type": 33, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 15 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 41, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 27, + 30, + 34, + 36, + 38 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 48, + "optional": false + }, + { + "name": "replayState", + "type": 60, + "optional": true + }, + { + "name": "type", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 49, + 52, + 54, + 56, + 58 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 2, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 2, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 61, + "optional": true + }, + { + "name": "response", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 62 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 65, + "optional": false + }, + { + "name": "usage", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 2, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 2, + "optional": true + }, + { + "name": "inputTokens", + "type": 2, + "optional": false + }, + { + "name": "outputTokens", + "type": 2, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 2, + "optional": true + }, + { + "name": "totalTokens", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "literal", + "value": "assistant/attempt" + } + ] + } + }, + { + "key": "event:assistant/message", + "kind": "event", + "event": "assistant/message", + "surface": true, + "digest": "1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "surfaceOp", + "type": 76, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 80, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "interrupted", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 11, + "optional": false + }, + { + "name": "stream", + "type": 33, + "optional": false + }, + { + "name": "turn", + "type": 11, + "optional": false + }, + { + "name": "usage", + "type": 70, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 19, + 22, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 2, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "isError", + "type": 23, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 32, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "union", + "types": [ + 35, + 39, + 72, + 74 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 36, + "optional": false + }, + { + "name": "dt", + "type": 37, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "array", + "element": 11 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 40, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 41, + 43, + 45, + 48, + 50, + 52, + 68 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 5, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 46, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 24, + 26, + 28 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 53, + "optional": false + }, + { + "name": "replayState", + "type": 65, + "optional": true + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 54, + 57, + 59, + 61, + 63 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 11, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 11, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 11, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 66, + "optional": true + }, + { + "name": "response", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 32 + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 69, + "optional": false + }, + { + "name": "usage", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 11, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 11, + "optional": true + }, + { + "name": "inputTokens", + "type": 11, + "optional": false + }, + { + "name": "outputTokens", + "type": 11, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 11, + "optional": true + }, + { + "name": "totalTokens", + "type": 11, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 37, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 36, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 37, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 36, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "union", + "types": [ + 77, + 79 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 11, + "optional": false + }, + { + "name": "op", + "type": 78, + "optional": false + }, + { + "name": "startSeq", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "literal", + "value": "assistant/message" + } + ] + } + }, + { + "key": "event:command/done", + "kind": "event", + "event": "command/done", + "surface": false, + "digest": "15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "commandId", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "sourceEventSeq", + "type": 6, + "optional": true + }, + { + "name": "text", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "literal", + "value": "success" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "command/done" + } + ] + } + }, + { + "key": "event:command/run", + "kind": "event", + "event": "command/run", + "surface": false, + "digest": "37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 2, + "optional": true + }, + { + "name": "commandId", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "command/run" + } + ] + } + }, + { + "key": "event:compaction/end", + "kind": "event", + "event": "compaction/end", + "surface": false, + "digest": "b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "error", + "type": 2, + "optional": true + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "compaction/end" + } + ] + } + }, + { + "key": "event:compaction/prune", + "kind": "event", + "event": "compaction/prune", + "surface": false, + "digest": "7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "shadowedRange", + "type": 2, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 4, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 3, + "optional": false + }, + { + "name": "start", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "compaction/prune" + } + ] + } + }, + { + "key": "event:compaction/start", + "kind": "event", + "event": "compaction/start", + "surface": false, + "digest": "db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "compaction/start" + } + ] + } + }, + { + "key": "event:compaction/summary", + "kind": "event", + "event": "compaction/summary", + "surface": false, + "digest": "f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 32 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 4, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": false + }, + { + "name": "shadowedRange", + "type": 29, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 30, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 11, + 13, + 15, + 17, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "isError", + "type": 9, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 4, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 5, + "optional": false + }, + { + "name": "start", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 5, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 5, + "optional": true + }, + { + "name": "inputTokens", + "type": 5, + "optional": false + }, + { + "name": "outputTokens", + "type": 5, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 5, + "optional": true + }, + { + "name": "totalTokens", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": true + }, + { + "name": "shadowedRange", + "type": 29, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 30, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compaction/summary" + } + ] + } + }, + { + "key": "event:deliverables/presented", + "kind": "event", + "event": "deliverables/presented", + "surface": false, + "digest": "13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 2, + "optional": false + }, + { + "name": "files", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 2, + "optional": true + }, + { + "name": "path", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "deliverables/presented" + } + ] + } + }, + { + "key": "event:feedback/message-delete", + "kind": "event", + "event": "feedback/message-delete", + "surface": false, + "digest": "3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "messageId", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "feedback/message-delete" + } + ] + } + }, + { + "key": "event:feedback/message-put", + "kind": "event", + "event": "feedback/message-put", + "surface": false, + "digest": "b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 16, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "item", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 3, + "optional": true + }, + { + "name": "createdAt", + "type": 11, + "optional": false + }, + { + "name": "messageId", + "type": 12, + "optional": false + }, + { + "name": "note", + "type": 12, + "optional": true + }, + { + "name": "rating", + "type": 13, + "optional": false + }, + { + "name": "updatedAt", + "type": 11, + "optional": false + }, + { + "name": "version", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "negative" + }, + { + "kind": "literal", + "value": "positive" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "feedback/message-put" + } + ] + } + }, + { + "key": "event:feedback/record", + "kind": "event", + "event": "feedback/record", + "surface": false, + "digest": "b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 11, + "optional": true + }, + { + "name": "seq", + "type": 12, + "optional": false + }, + { + "name": "time", + "type": 12, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 2, + "optional": true + }, + { + "name": "text", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "feedback/record" + } + ] + } + }, + { + "key": "event:goal/change", + "kind": "event", + "event": "goal/change", + "surface": false, + "digest": "763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 23, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 9 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "cleared", + "type": 3, + "optional": false + }, + { + "name": "clearedAt", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "operation", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "revision", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "goal/change" + }, + { + "kind": "literal", + "value": "clear" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "createdAt", + "type": 5, + "optional": false + }, + { + "name": "goal", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "operation", + "type": 17, + "optional": false + }, + { + "name": "roundsStarted", + "type": 5, + "optional": false + }, + { + "name": "updatedAt", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedReason", + "type": 11, + "optional": true + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "maxGoalRounds", + "type": 5, + "optional": false + }, + { + "name": "objective", + "type": 4, + "optional": false + }, + { + "name": "phase", + "type": 12, + "optional": false + }, + { + "name": "revision", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 4, + "optional": false + }, + { + "name": "message", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "paused" + }, + { + "kind": "union", + "types": [ + 15, + 18, + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "block" + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "edit" + }, + { + "kind": "literal", + "value": "pause" + }, + { + "kind": "literal", + "value": true + } + ] + } + }, + { + "key": "event:hook/invoked", + "kind": "event", + "event": "hook/invoked", + "surface": false, + "digest": "8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "dialect", + "type": 2, + "optional": false + }, + { + "name": "handlerId", + "type": 5, + "optional": false + }, + { + "name": "matcher", + "type": 5, + "optional": true + }, + { + "name": "point", + "type": 5, + "optional": false + }, + { + "name": "turn", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "claude-code" + }, + { + "kind": "literal", + "value": "codex" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "hook/invoked" + } + ] + } + }, + { + "key": "event:hook/result", + "kind": "event", + "event": "hook/result", + "surface": false, + "digest": "e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "decision", + "type": 2, + "optional": false + }, + { + "name": "durationMs", + "type": 3, + "optional": false + }, + { + "name": "exitCode", + "type": 3, + "optional": true + }, + { + "name": "handlerId", + "type": 2, + "optional": false + }, + { + "name": "point", + "type": 2, + "optional": false + }, + { + "name": "stderrSummary", + "type": 2, + "optional": true + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "hook/result" + } + ] + } + }, + { + "key": "event:image/offload", + "kind": "event", + "event": "image/offload", + "surface": false, + "digest": "b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "targets", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "imageIndexes", + "type": 4, + "optional": false + }, + { + "name": "seq", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image/offload" + } + ] + } + }, + { + "key": "event:llm/retry", + "kind": "event", + "event": "llm/retry", + "surface": false, + "digest": "525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 9, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 3, + "optional": false + }, + { + "name": "failure", + "type": 4, + "optional": false + }, + { + "name": "maxRetries", + "type": 3, + "optional": false + }, + { + "name": "mode", + "type": 6, + "optional": false + }, + { + "name": "policyKey", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "retry", + "type": 3, + "optional": false + }, + { + "name": "retryId", + "type": 5, + "optional": false + }, + { + "name": "step", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 5, + "optional": false + }, + { + "name": "message", + "type": 5, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 5, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "normal" + }, + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 3, + "optional": false + }, + { + "name": "failure", + "type": 4, + "optional": false + }, + { + "name": "mode", + "type": 8, + "optional": false + }, + { + "name": "policyKey", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "retry", + "type": 3, + "optional": false + }, + { + "name": "retryId", + "type": 5, + "optional": false + }, + { + "name": "step", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "always" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "llm/retry" + } + ] + } + }, + { + "key": "event:llm/retry-started", + "kind": "event", + "event": "llm/retry-started", + "surface": false, + "digest": "48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "retry", + "type": 2, + "optional": false + }, + { + "name": "retryId", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "llm/retry-started" + } + ] + } + }, + { + "key": "event:model/selection", + "kind": "event", + "event": "model/selection", + "surface": false, + "digest": "35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "model/selection" + } + ] + } + }, + { + "key": "event:permission/preset", + "kind": "event", + "event": "permission/preset", + "surface": false, + "digest": "5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "preset", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "permission/preset" + } + ] + } + }, + { + "key": "event:plan/mode", + "kind": "event", + "event": "plan/mode", + "surface": false, + "digest": "a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "active", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "plan/mode" + } + ] + } + }, + { + "key": "event:request/context", + "kind": "event", + "event": "request/context", + "surface": false, + "digest": "37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "contextWindow", + "type": 2, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "systemPromptUpdate", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "in-history" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "request/context" + } + ] + } + }, + { + "key": "event:request/header", + "kind": "event", + "event": "request/header", + "surface": false, + "digest": "8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "header", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 13, + "optional": false + }, + { + "name": "startsSeries", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 3, + "optional": true + }, + { + "name": "config", + "type": 5, + "optional": false + }, + { + "name": "tools", + "type": 9, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 6, + "optional": true + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 7, + "optional": true + }, + { + "name": "stop", + "type": 8, + "optional": true + }, + { + "name": "temperature", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "parameters", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 7, + "value": 12 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "union", + "types": [ + 14, + 15, + 16, + 17 + ] + }, + { + "kind": "literal", + "value": "initial" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "series" + }, + { + "kind": "literal", + "value": "change" + }, + { + "kind": "literal", + "value": "request/header" + } + ] + } + }, + { + "key": "event:sandbox/mode", + "kind": "event", + "event": "sandbox/mode", + "surface": false, + "digest": "516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 8, + "optional": false + }, + { + "name": "time", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "mode", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "danger-full-access" + }, + { + "kind": "literal", + "value": "read-only" + }, + { + "kind": "literal", + "value": "workspace-write" + }, + { + "kind": "literal", + "value": "delegation" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "sandbox/mode" + } + ] + } + }, + { + "key": "event:schedule/change", + "kind": "event", + "event": "schedule/change", + "surface": false, + "digest": "2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 19, + "optional": true + }, + { + "name": "seq", + "type": 13, + "optional": false + }, + { + "name": "time", + "type": 13, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 6, + 8, + 9 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "acceptedAt", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "operation", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "dispatch" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "operation", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "delete" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "operation", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "operation", + "type": 10, + "optional": false + }, + { + "name": "schedule", + "type": 11, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "union", + "types": [ + 12, + 15, + 17 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "afterSeconds", + "type": 13, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 14, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "after" + }, + { + "kind": "object", + "properties": [ + { + "name": "everySeconds", + "type": 13, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "every" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "at" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "schedule/change" + } + ] + } + }, + { + "key": "event:session-log-deepseek/delivery-accepted", + "kind": "event", + "event": "session-log-deepseek/delivery-accepted", + "surface": false, + "digest": "d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "sessionFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "sessionId", + "type": 3, + "optional": false + }, + { + "name": "throughSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "session-log-deepseek/delivery-accepted" + } + ] + } + }, + { + "key": "event:session/end-seed", + "kind": "event", + "event": "session/end-seed", + "surface": false, + "digest": "5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "inherited", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "session/end-seed" + } + ] + } + }, + { + "key": "event:session/title", + "kind": "event", + "event": "session/title", + "surface": false, + "digest": "1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 13, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "messageSeqs", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": false + }, + { + "name": "title", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 5, + 9, + 11 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": true + }, + { + "name": "provider", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "provider" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 8, + "optional": false + }, + { + "name": "provider", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "fallback" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "session/title" + } + ] + } + }, + { + "key": "event:session/title-llm-request", + "kind": "event", + "event": "session/title-llm-request", + "surface": false, + "digest": "e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 19, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 91, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 2, + "optional": false + }, + { + "name": "messageSeqs", + "type": 3, + "optional": false + }, + { + "name": "messages", + "type": 4, + "optional": false + }, + { + "name": "route", + "type": 90, + "optional": false + }, + { + "name": "system", + "type": 9, + "optional": false + }, + { + "name": "titleProvider", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 9, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 11, + 21, + 24, + 27, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 9, + "optional": false + }, + { + "name": "id", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 12, + "optional": false + }, + { + "name": "offloaded", + "type": 19, + "optional": true + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 9, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 13, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": true + }, + { + "name": "originalDimensions", + "type": 18, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 14, + 15, + 16, + 17 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 22, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 9, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "isError", + "type": 25, + "optional": true + }, + { + "name": "toolCallId", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "union", + "types": [ + 32, + 33, + 34 + ] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 36, + 45, + 47, + 48, + 51, + 56, + 58, + 63, + 64, + 65, + 67, + 69, + 70, + 77, + 79, + 81, + 83, + 85, + 88, + 89 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 19, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 9, + "optional": true + }, + { + "name": "changes", + "type": 37, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 38 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 39, + "optional": false + }, + { + "name": "digest", + "type": 9, + "optional": true + }, + { + "name": "path", + "type": 9, + "optional": false + }, + { + "name": "scope", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 40, + 41, + 42 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 9, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 9, + "optional": true + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "rpcId", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 9, + "optional": false + }, + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "provider", + "type": 9, + "optional": false + }, + { + "name": "ruleId", + "type": 9, + "optional": false + }, + { + "name": "source", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 52, + "optional": false + }, + { + "name": "form", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "update", + "type": 19, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 53 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + }, + { + "name": "sections", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 62 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 9, + "optional": false + }, + { + "name": "text", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "references", + "type": 72, + "optional": false + }, + { + "name": "version", + "type": 76, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 73 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 74, + "optional": false + }, + { + "name": "compacted", + "type": 25, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 9, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 9, + "optional": false + }, + { + "name": "truncated", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 75 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "senderSessionId", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "senderSessionId", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 9, + "optional": false + }, + { + "name": "kind", + "type": 82, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 84, + "optional": false + }, + { + "name": "messageId", + "type": 9, + "optional": false + }, + { + "name": "senderId", + "type": 9, + "optional": false + }, + { + "name": "senderName", + "type": 9, + "optional": false + }, + { + "name": "teamId", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 86, + "optional": false + }, + { + "name": "model", + "type": 9, + "optional": false + }, + { + "name": "provider", + "type": 9, + "optional": false + }, + { + "name": "replayState", + "type": 87, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 9, + "optional": false + }, + { + "name": "provider", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session/title-llm-request" + } + ] + } + }, + { + "key": "event:step/end", + "kind": "event", + "event": "step/end", + "surface": false, + "digest": "e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "step/end" + } + ] + } + }, + { + "key": "event:step/start", + "kind": "event", + "event": "step/start", + "surface": false, + "digest": "4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "step/start" + } + ] + } + }, + { + "key": "event:subagent/catalog", + "kind": "event", + "event": "subagent/catalog", + "surface": false, + "digest": "ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 9, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 3, + "optional": false + }, + { + "name": "childId", + "type": 4, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": false + }, + { + "name": "mode", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "literal", + "value": 0 + }, + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 3, + "optional": false + }, + { + "name": "childId", + "type": 4, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": true + }, + { + "name": "mode", + "type": 8, + "optional": false + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "one-shot" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "subagent/catalog" + } + ] + } + }, + { + "key": "event:subagent/descriptor", + "kind": "event", + "event": "subagent/descriptor", + "surface": false, + "digest": "b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 10, + "optional": true + }, + { + "name": "seq", + "type": 7, + "optional": false + }, + { + "name": "time", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 8 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "agentModel", + "type": 3, + "optional": true + }, + { + "name": "agentProvider", + "type": 3, + "optional": true + }, + { + "name": "agentReasoningEffort", + "type": 3, + "optional": true + }, + { + "name": "label", + "type": 3, + "optional": false + }, + { + "name": "mode", + "type": 4, + "optional": false + }, + { + "name": "persona", + "type": 3, + "optional": true + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "toolFilter", + "type": 5, + "optional": true + }, + { + "name": "version", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "object", + "properties": [ + { + "name": "allow", + "type": 6, + "optional": true + }, + { + "name": "deny", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "label", + "type": 3, + "optional": true + }, + { + "name": "mode", + "type": 9, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "one-shot" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "subagent/descriptor" + } + ] + } + }, + { + "key": "event:subagent/model-selection-policy", + "kind": "event", + "event": "subagent/model-selection-policy", + "surface": false, + "digest": "a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "allowedModels", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "subagent/model-selection-policy" + } + ] + } + }, + { + "key": "event:system/message", + "kind": "event", + "event": "system/message", + "surface": true, + "digest": "69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 17, + "optional": true + }, + { + "name": "seq", + "type": 10, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 47, + "optional": true + }, + { + "name": "surfaceOp", + "type": 48, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 10, + "optional": false + }, + { + "name": "turn", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 19, + 22, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 23, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "union", + "types": [ + 31, + 36, + 38, + 40, + 42, + 44, + 46 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + }, + { + "name": "sections", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 35 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "union", + "types": [ + 49, + 51 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 10, + "optional": false + }, + { + "name": "op", + "type": 50, + "optional": false + }, + { + "name": "startSeq", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "literal", + "value": "system/message" + } + ] + } + }, + { + "key": "event:team/member", + "kind": "event", + "event": "team/member", + "surface": false, + "digest": "4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 12, + "optional": true + }, + { + "name": "seq", + "type": 13, + "optional": false + }, + { + "name": "time", + "type": 13, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "member", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "context", + "type": 3, + "optional": false + }, + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "error", + "type": 6, + "optional": true + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "phase", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "fork" + }, + { + "kind": "literal", + "value": "fresh" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 8, + 9, + 10 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "literal", + "value": "provisioning" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "team/member" + } + ] + } + }, + { + "key": "event:team/message/delivered", + "kind": "event", + "event": "team/message/delivered", + "surface": false, + "digest": "48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "messageId", + "type": 2, + "optional": false + }, + { + "name": "targetId", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "team/message/delivered" + } + ] + } + }, + { + "key": "event:team/message/queued", + "kind": "event", + "event": "team/message/queued", + "surface": false, + "digest": "443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 24, + "optional": true + }, + { + "name": "seq", + "type": 17, + "optional": false + }, + { + "name": "time", + "type": 17, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "targetId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 9, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 6, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": "team/message/queued" + } + ] + } + }, + { + "key": "event:team/task", + "kind": "event", + "event": "team/task", + "surface": false, + "digest": "d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 12, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "task", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedBy", + "type": 3, + "optional": false + }, + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "ownerId", + "type": 4, + "optional": true + }, + { + "name": "revision", + "type": 5, + "optional": false + }, + { + "name": "status", + "type": 6, + "optional": false + }, + { + "name": "subject", + "type": 4, + "optional": false + }, + { + "name": "writeScopes", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 7, + 8, + 9, + 10 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "deleted" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "team/task" + } + ] + } + }, + { + "key": "event:todo/write", + "kind": "event", + "event": "todo/write", + "surface": false, + "digest": "b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 9, + "optional": true + }, + { + "name": "seq", + "type": 10, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "todos", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "status", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "todo/write" + } + ] + } + }, + { + "key": "event:tool-workflow/agent-end", + "kind": "event", + "event": "tool-workflow/agent-end", + "surface": false, + "digest": "babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 8, + "optional": true + }, + { + "name": "seq", + "type": 7, + "optional": false + }, + { + "name": "time", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "outcome", + "type": 2, + "optional": false + }, + { + "name": "runId", + "type": 6, + "optional": false + }, + { + "name": "seq", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "tool-workflow/agent-end" + } + ] + } + }, + { + "key": "event:tool-workflow/agent-start", + "kind": "event", + "event": "tool-workflow/agent-start", + "surface": false, + "digest": "5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "childId", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 2, + "optional": false + }, + { + "name": "phase", + "type": 2, + "optional": true + }, + { + "name": "runId", + "type": 2, + "optional": false + }, + { + "name": "seq", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "tool-workflow/agent-start" + } + ] + } + }, + { + "key": "event:tool-workflow/run-end", + "kind": "event", + "event": "tool-workflow/run-end", + "surface": false, + "digest": "42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 8, + "optional": false + }, + { + "name": "time", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "runId", + "type": 2, + "optional": false + }, + { + "name": "stopReason", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-workflow/run-end" + } + ] + } + }, + { + "key": "event:tool-workflow/run-start", + "kind": "event", + "event": "tool-workflow/run-start", + "surface": false, + "digest": "c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "runId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-workflow/run-start" + } + ] + } + }, + { + "key": "event:tool/call", + "kind": "event", + "event": "tool/call", + "surface": false, + "digest": "3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "callId", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "tool/call" + } + ] + } + }, + { + "key": "event:tool/ptc-dispatch", + "kind": "event", + "event": "tool/ptc-dispatch", + "surface": false, + "digest": "b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 24, + "optional": true + }, + { + "name": "seq", + "type": 17, + "optional": false + }, + { + "name": "time", + "type": 17, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "error", + "type": 29, + "optional": true + }, + { + "name": "isError", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "parentCallId", + "type": 7, + "optional": false + }, + { + "name": "rootCallId", + "type": 7, + "optional": false + }, + { + "name": "subCallId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 9, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 6, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "reason", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool/ptc-dispatch" + } + ] + } + }, + { + "key": "event:tool/ptc-dispatch-start", + "kind": "event", + "event": "tool/ptc-dispatch-start", + "surface": false, + "digest": "ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "parentCallId", + "type": 3, + "optional": false + }, + { + "name": "rootCallId", + "type": 3, + "optional": false + }, + { + "name": "subCallId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool/ptc-dispatch-start" + } + ] + } + }, + { + "key": "event:tool/result", + "kind": "event", + "event": "tool/result", + "surface": true, + "digest": "29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 24, + "optional": true + }, + { + "name": "seq", + "type": 17, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 38, + "optional": true + }, + { + "name": "surfaceOp", + "type": 39, + "optional": false + }, + { + "name": "time", + "type": 17, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "meta", + "type": 34, + "optional": true + }, + { + "name": "step", + "type": 17, + "optional": false + }, + { + "name": "turn", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "reason", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 6, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "isError", + "type": 29, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 8 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "union", + "types": [ + 3, + 17, + 29, + 35, + 36, + 37 + ] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 34 + } + ] + }, + { + "kind": "array", + "element": 17 + }, + { + "kind": "union", + "types": [ + 40, + 41 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 17, + "optional": false + }, + { + "name": "op", + "type": 42, + "optional": false + }, + { + "name": "startSeq", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "tool/result" + } + ] + } + }, + { + "key": "event:turn/end", + "kind": "event", + "event": "turn/end", + "surface": false, + "digest": "bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 29, + "optional": true + }, + { + "name": "seq", + "type": 14, + "optional": false + }, + { + "name": "time", + "type": 14, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 5, + 7, + 9, + 11, + 16 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 12, + "optional": false + }, + { + "name": "kind", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 13, + "optional": false + }, + { + "name": "message", + "type": 13, + "optional": false + }, + { + "name": "offloadImages", + "type": 14, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 14, + "optional": true + }, + { + "name": "requestId", + "type": 13, + "optional": true + }, + { + "name": "status", + "type": 14, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 17, + "optional": false + }, + { + "name": "reason", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 19, + 21, + 23, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "reason", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "turn/end" + } + ] + } + }, + { + "key": "event:turn/start", + "kind": "event", + "event": "turn/start", + "surface": false, + "digest": "aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "turn/start" + } + ] + } + }, + { + "key": "event:user/message", + "kind": "event", + "event": "user/message", + "surface": true, + "digest": "314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 16, + "optional": true + }, + { + "name": "seq", + "type": 9, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 84, + "optional": true + }, + { + "name": "surfaceOp", + "type": 85, + "optional": false + }, + { + "name": "time", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 88, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 18, + 21, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 8, + "optional": false + }, + { + "name": "offloaded", + "type": 16, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "mediaType", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 15, + "optional": true + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 11, + 12, + 13, + 14 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 22, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 30, + 39, + 41, + 42, + 45, + 50, + 52, + 57, + 58, + 59, + 61, + 63, + 64, + 71, + 73, + 75, + 77, + 79, + 82, + 83 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 16, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 31, + "optional": false + }, + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 32 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 33, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 34, + 35, + 36 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 46, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "update", + "type": 16, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 47 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 53, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "sections", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 56 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 60, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 60, + "optional": false + }, + { + "name": "kind", + "type": 65, + "optional": false + }, + { + "name": "references", + "type": 66, + "optional": false + }, + { + "name": "version", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 67 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 9, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 68, + "optional": false + }, + { + "name": "compacted", + "type": 22, + "optional": false + }, + { + "name": "inputIndex", + "type": 9, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 9, + "optional": false + }, + { + "name": "omittedMessages", + "type": 9, + "optional": false + }, + { + "name": "originalMessages", + "type": 9, + "optional": false + }, + { + "name": "retainedMessages", + "type": 9, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 69 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 72, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 76, + "optional": false + }, + { + "name": "revision", + "type": 9, + "optional": false + }, + { + "name": "round", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 81, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 9 + }, + { + "kind": "union", + "types": [ + 86, + 87 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 9, + "optional": false + }, + { + "name": "op", + "type": 35, + "optional": false + }, + { + "name": "startSeq", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user/message" + } + ] + } + }, + { + "key": "event:web/deepseek-search-llm-request", + "kind": "event", + "event": "web/deepseek-search-llm-request", + "surface": false, + "digest": "cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 15, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "apiVersion", + "type": 2, + "optional": false + }, + { + "name": "body", + "type": 3, + "optional": false + }, + { + "name": "endpoint", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "max_tokens", + "type": 4, + "optional": false + }, + { + "name": "messages", + "type": 5, + "optional": false + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "tools", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 6, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 8, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 12, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "max_uses", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 13, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "web_search" + }, + { + "kind": "literal", + "value": "web_search_20250305" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "web/deepseek-search-llm-request" + } + ] + } + } + ], + "types": [ + { + "digest": "0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "web_search_20250305" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + } + ] + }, + "names": [ + "event:turn/end.data.reason[2]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "product-interaction" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "ask" + }, + { + "kind": "literal", + "value": "never" + } + ] + }, + "names": [ + "packages/interaction/user-approval/src/index.ts#ApprovalPolicy" + ], + "sources": [ + "packages/interaction/user-approval/src/index.ts" + ] + }, + { + "digest": "0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#SessionSeq" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "071d92b9dac661fcc826c678cf64d188f26fb93aab79c627b11a03acdd34dfca", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 5, + 31, + 34, + 36, + 38, + 55 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 7, + 9, + 19, + 22, + 26, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 23, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 32, + "optional": false + }, + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 25, + 27, + 29 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 39, + "optional": false + }, + { + "name": "replayState", + "type": 51, + "optional": true + }, + { + "name": "type", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 40, + 43, + 45, + 47, + 49 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 2, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 52, + "optional": true + }, + { + "name": "response", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 53 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 56, + "optional": false + }, + { + "name": "usage", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 3, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 3, + "optional": true + }, + { + "name": "inputTokens", + "type": 3, + "optional": false + }, + { + "name": "outputTokens", + "type": 3, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 3, + "optional": true + }, + { + "name": "totalTokens", + "type": 3, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#StreamChunk" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/session/session-title/src/types.ts#SessionTitleModelIdentity", + "packages/subagent/tool-subagent/src/model-selection.ts#AllowedModelRoute" + ], + "sources": [ + "packages/session/session-title/src/types.ts", + "packages/subagent/tool-subagent/src/model-selection.ts" + ] + }, + { + "digest": "07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "security-privacy-permission" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + }, + { + "name": "reason", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 3, + 5, + 7, + 10, + 12 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + }, + { + "name": "reason", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + } + ] + }, + "names": [ + "event:turn/end.data.reason[1]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "subagent/model-selection-policy" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 1, + "value": 2 + } + ] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "event:request/header.data.header.tools[0].parameters" + ], + "sources": [] + }, + { + "digest": "0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 1, + "optional": true + }, + { + "name": "response", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ReplayEnvelope" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "turn/start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/goal/goal/src/types.ts#GoalRef" + ], + "sources": [ + "packages/goal/goal/src/types.ts" + ] + }, + { + "digest": "0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "messageId", + "type": 1, + "optional": false + }, + { + "name": "targetId", + "type": 1, + "optional": false + }, + { + "name": "teamId", + "type": 1, + "optional": false + }, + { + "name": "version", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": 2 + } + ] + }, + "names": [ + "event:team/message/delivered.data" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "usage" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "0c3f4d2248d9bc9700e2d7253fa71aa9935f5c39af6f11de5727f08cccaf8383", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 1, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "targetId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 8, + 10, + 12, + 14, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 5, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 15, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": 2 + } + ] + }, + "names": [ + "event:team/message/queued.data" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "0c6412d3ba5e41adfaa6929c7d4093f2d52d8598c03f35844fc0d55e3070a3b1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "stream", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 9, + 67, + 69 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 5, + "optional": false + }, + { + "name": "dt", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "time0", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 1 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 10, + "optional": false + }, + { + "name": "time", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 11, + 13, + 39, + 42, + 44, + 46, + 63 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 14, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 15, + 17, + 27, + 30, + 34, + 36 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 31, + "optional": false + }, + { + "name": "isError", + "type": 32, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 14 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 40, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 16, + 26, + 29, + 33, + 35, + 37 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 47, + "optional": false + }, + { + "name": "replayState", + "type": 59, + "optional": true + }, + { + "name": "type", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 48, + 51, + 53, + 55, + 57 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "message", + "type": 6, + "optional": false + }, + { + "name": "offloadImages", + "type": 1, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 1, + "optional": true + }, + { + "name": "requestId", + "type": 6, + "optional": true + }, + { + "name": "status", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 60, + "optional": true + }, + { + "name": "response", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 61 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 64, + "optional": false + }, + { + "name": "usage", + "type": 65, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 1, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 1, + "optional": true + }, + { + "name": "inputTokens", + "type": 1, + "optional": false + }, + { + "name": "outputTokens", + "type": 1, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 1, + "optional": true + }, + { + "name": "totalTokens", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "texts", + "type": 5, + "optional": false + }, + { + "name": "time0", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 68, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "texts", + "type": 5, + "optional": false + }, + { + "name": "time0", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [ + "event:assistant/attempt.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "allowedModels", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:subagent/model-selection-policy.data" + ], + "sources": [ + "packages/subagent/tool-subagent/src/model-selection-state.ts" + ] + }, + { + "digest": "0ddab4577db37a3e0d9e3a91761735c8ef6f5629d526ab8ecaeeea19c097c8f8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + }, + { + "name": "plugin", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[1]", + "event:system/message.data.message.source[0]" + ], + "sources": [] + }, + { + "digest": "0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 1, + "optional": false + }, + { + "name": "childId", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 2, + "optional": false + }, + { + "name": "mode", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "literal", + "value": 0 + } + ] + }, + "names": [ + "event:subagent/catalog.data[1]" + ], + "sources": [] + }, + { + "digest": "0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "schedule/change" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions" + ], + "sources": [ + "packages/attachment/attachment/src/types.ts" + ] + }, + { + "digest": "10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "compaction/prune" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "surfaceOp", + "type": 76, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 80, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "interrupted", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 11, + "optional": false + }, + { + "name": "stream", + "type": 33, + "optional": false + }, + { + "name": "turn", + "type": 11, + "optional": false + }, + { + "name": "usage", + "type": 70, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 19, + 22, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 2, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "isError", + "type": 23, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 32, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "union", + "types": [ + 35, + 39, + 72, + 74 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 36, + "optional": false + }, + { + "name": "dt", + "type": 37, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "array", + "element": 11 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 40, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 41, + 43, + 45, + 48, + 50, + 52, + 68 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 5, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 46, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 24, + 26, + 28 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 53, + "optional": false + }, + { + "name": "replayState", + "type": 65, + "optional": true + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 54, + 57, + 59, + 61, + 63 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 11, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 11, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 11, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 66, + "optional": true + }, + { + "name": "response", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 32 + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 69, + "optional": false + }, + { + "name": "usage", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 11, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 11, + "optional": true + }, + { + "name": "inputTokens", + "type": 11, + "optional": false + }, + { + "name": "outputTokens", + "type": 11, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 11, + "optional": true + }, + { + "name": "totalTokens", + "type": 11, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 37, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 36, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 37, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 36, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "union", + "types": [ + 77, + 79 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 11, + "optional": false + }, + { + "name": "op", + "type": 78, + "optional": false + }, + { + "name": "startSeq", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "literal", + "value": "assistant/message" + } + ] + }, + "names": [ + "event:assistant/message" + ], + "sources": [] + }, + { + "digest": "119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "dialect", + "type": 1, + "optional": false + }, + { + "name": "handlerId", + "type": 4, + "optional": false + }, + { + "name": "matcher", + "type": 4, + "optional": true + }, + { + "name": "point", + "type": 4, + "optional": false + }, + { + "name": "turn", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "claude-code" + }, + { + "kind": "literal", + "value": "codex" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:hook/invoked.data" + ], + "sources": [ + "packages/hooks/hook-protocol/src/types.ts" + ] + }, + { + "digest": "11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "policy", + "type": 1, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "ask" + }, + { + "kind": "literal", + "value": "never" + }, + { + "kind": "literal", + "value": "delegation" + } + ] + }, + "names": [ + "event:approval/policy.data" + ], + "sources": [ + "packages/interaction/user-approval/src/index.ts" + ] + }, + { + "digest": "12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "read-only" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 1, + "optional": false + }, + { + "name": "offloaded", + "type": 10, + "optional": true + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "mediaType", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 9, + "optional": true + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 5, + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ImageBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "137ac60e26bcb192210d9a32a704b73b0924ed34019323defa1b787be95bd45e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": 3 + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 2, + "optional": false + }, + { + "name": "files", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 2, + "optional": true + }, + { + "name": "path", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "deliverables/presented" + } + ] + }, + "names": [ + "event:deliverables/presented" + ], + "sources": [] + }, + { + "digest": "14230f9b8b5797bb7e8c621fa636531cfbde2ffba1ef5f1fd058216ff21952a0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "chunk" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "142c37d302aa22a0a57915b5255939d3ca91c1811ca13fddcf84cf76ea00758a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "always" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "commandId", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "sourceEventSeq", + "type": 6, + "optional": true + }, + { + "name": "text", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "literal", + "value": "success" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "command/done" + } + ] + }, + "names": [ + "event:command/done" + ], + "sources": [] + }, + { + "digest": "1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 1, + "optional": false + }, + { + "name": "files", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 1, + "optional": true + }, + { + "name": "path", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:deliverables/presented.data" + ], + "sources": [ + "packages/fs/tool-present/src/types.ts" + ] + }, + { + "digest": "15495614ccfa9cbdeefb0ec2abd76406435f4c6ff3dae42acae8e09ef42025c9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "codex" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "never" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "relay" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "17aae616ef020b8b9f011ec398ec935450fb06d3e2a0722c456f63aeaf5ff728", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "at" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "inherited", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + } + ] + }, + "names": [ + "event:session/end-seed.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "operation", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "delete" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#ScheduleDeleteChange" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 2, + "optional": false + }, + { + "name": "cwd", + "type": 1, + "optional": true + }, + { + "name": "delegationDepth", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "isSeeded", + "type": 3, + "optional": false + }, + { + "name": "origin", + "type": 4, + "optional": true + }, + { + "name": "parentSession", + "type": 1, + "optional": true + }, + { + "name": "type", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "subagent" + }, + { + "kind": "literal", + "value": "session" + } + ] + }, + "names": [ + "packages/session/session-persistence-jsonl/src/format.ts#HeaderLine" + ], + "sources": [ + "packages/session/session-persistence-jsonl/src/format.ts" + ] + }, + { + "digest": "18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "team/member" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "18fce9540bb20897a66275499faee6b8296c97e9901fa1ff45a191772448ad1a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "danger-full-access" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "skill-invocation" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1986c2664009c99155e44795676c887fa67f7c55cd2d5e6b648ff763e0ab033a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "compaction/end" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1a2718b00937b236a0d0910ef5dab2f9f8b65e4bde410cc21f15fbbf29f584d3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "deliverables/presented" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "literal", + "value": "success" + } + ] + }, + "names": [ + "event:command/done.data.kind" + ], + "sources": [] + }, + { + "digest": "1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "fallback" + } + ] + }, + "names": [ + "event:session/title.data.source[0]" + ], + "sources": [ + "packages/session/session-title/src/types.ts" + ] + }, + { + "digest": "1b573e2d5c094fa87e2a8bf409ddd4ac5ba92a123085e168de44b9ccdbd5244c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 2, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 26, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 2, + 5, + 8, + 10, + 12, + 23 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 13, + "optional": false + }, + { + "name": "offloaded", + "type": 21, + "optional": true + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 14, + "optional": false + }, + { + "name": "height", + "type": 14, + "optional": false + }, + { + "name": "mediaType", + "type": 15, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 20, + "optional": true + }, + { + "name": "width", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 16, + 17, + 18, + 19 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 14, + "optional": false + }, + { + "name": "width", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 24, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 14, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#ToolResultMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 13, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "messageSeqs", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": false + }, + { + "name": "title", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 5, + 9, + 11 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": true + }, + { + "name": "provider", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "provider" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 8, + "optional": false + }, + { + "name": "provider", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "fallback" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "session/title" + } + ] + }, + "names": [ + "event:session/title" + ], + "sources": [] + }, + { + "digest": "1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "session/end-seed" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "system/message" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "imageIndexes", + "type": 1, + "optional": false + }, + { + "name": "seq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget" + ], + "sources": [ + "packages/compaction/compaction-image-offload/src/projection.ts" + ] + }, + { + "digest": "1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "model/selection" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "pause" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 2, + "optional": true + }, + { + "name": "path", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:deliverables/presented.data.files" + ], + "sources": [] + }, + { + "digest": "1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "createdAt", + "type": 1, + "optional": false + }, + { + "name": "goal", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 10, + "optional": false + }, + { + "name": "operation", + "type": 11, + "optional": false + }, + { + "name": "roundsStarted", + "type": 1, + "optional": false + }, + { + "name": "updatedAt", + "type": 1, + "optional": false + }, + { + "name": "version", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedReason", + "type": 3, + "optional": true + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "maxGoalRounds", + "type": 1, + "optional": false + }, + { + "name": "objective", + "type": 4, + "optional": false + }, + { + "name": "phase", + "type": 5, + "optional": false + }, + { + "name": "revision", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 4, + "optional": false + }, + { + "name": "message", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 6, + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "paused" + }, + { + "kind": "literal", + "value": "goal/change" + }, + { + "kind": "union", + "types": [ + 8, + 12, + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "block" + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "literal", + "value": "edit" + }, + { + "kind": "literal", + "value": "pause" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta" + ], + "sources": [ + "packages/goal/goal/src/domain.ts" + ] + }, + { + "digest": "1e0b0b66b6f0c53fc72e52289d06b4708d776f1ca9df4c86a22bff621d403cf0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "aborted" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1e346446e183ee76f48d7994c97ecb302bddc682abb60b8a10ea0bb26223a69c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "block" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1ebc6f9ff3aa9e3a38f8695f49bacdab1f8b7a3832741853ca46f40af56ccd01", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "completed" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-call" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 4, + 6, + 8, + 10 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#TurnEndCancelCause" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "2074f40221b76c75fd314246db558965dc3477dfb440bcc952b1eedc9778e366", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 1, + "optional": false + }, + { + "name": "step", + "type": 9, + "optional": false + }, + { + "name": "turn", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 18, + 21, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 8, + "optional": false + }, + { + "name": "offloaded", + "type": 16, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "mediaType", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 15, + "optional": true + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 11, + 12, + 13, + 14 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 22, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "union", + "types": [ + 30, + 35, + 37, + 39, + 41, + 43, + 45 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 31, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "sections", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:system/message.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "active", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + } + ] + }, + "names": [ + "event:plan/mode.data" + ], + "sources": [ + "packages/plan/plan-mode/src/index.ts" + ] + }, + { + "digest": "2142e391b9ccb60d487afcf373ce74db98d952f69e8289eddb352a7e16e996c5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "cancelled" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + }, + { + "name": "messageId", + "type": 2, + "optional": false + }, + { + "name": "senderId", + "type": 2, + "optional": false + }, + { + "name": "senderName", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/experimental/agent-team/src/types.ts#TeamMessageSource" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "goal/change" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "23c7cce57d20589897f4e2bd5898affc6fc611b87cd0cc8b95be1cfdd8b3a7eb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 27, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 17, + 20, + 23, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 7, + "optional": false + }, + { + "name": "offloaded", + "type": 15, + "optional": true + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 8, + "optional": false + }, + { + "name": "height", + "type": 8, + "optional": false + }, + { + "name": "mediaType", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 14, + "optional": true + }, + { + "name": "width", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 10, + 11, + 12, + 13 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 8, + "optional": false + }, + { + "name": "width", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 8, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "isError", + "type": 21, + "optional": true + }, + { + "name": "toolCallId", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "union", + "types": [ + 28, + 29, + 30 + ] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 32, + 41, + 43, + 44, + 47, + 52, + 54, + 59, + 60, + 61, + 63, + 65, + 66, + 73, + 75, + 77, + 79, + 81, + 84, + 85 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 15, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 4, + "optional": true + }, + { + "name": "changes", + "type": 33, + "optional": false + }, + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 35, + "optional": false + }, + { + "name": "digest", + "type": 4, + "optional": true + }, + { + "name": "path", + "type": 4, + "optional": false + }, + { + "name": "scope", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 36, + 37, + 38 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 4, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 4, + "optional": false + }, + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "ruleId", + "type": 4, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 48, + "optional": false + }, + { + "name": "form", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "update", + "type": 15, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 49 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "sections", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 58 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 64, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 67, + "optional": false + }, + { + "name": "references", + "type": 68, + "optional": false + }, + { + "name": "version", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 69 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 8, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 70, + "optional": false + }, + { + "name": "compacted", + "type": 21, + "optional": false + }, + { + "name": "inputIndex", + "type": 8, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": false + }, + { + "name": "omittedBytes", + "type": 8, + "optional": false + }, + { + "name": "omittedMessages", + "type": 8, + "optional": false + }, + { + "name": "originalMessages", + "type": 8, + "optional": false + }, + { + "name": "retainedMessages", + "type": 8, + "optional": false + }, + { + "name": "sessionId", + "type": 4, + "optional": false + }, + { + "name": "truncated", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 71 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 64, + "optional": false + }, + { + "name": "kind", + "type": 76, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "revision", + "type": 8, + "optional": false + }, + { + "name": "round", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "messageId", + "type": 4, + "optional": false + }, + { + "name": "senderId", + "type": 4, + "optional": false + }, + { + "name": "senderName", + "type": 4, + "optional": false + }, + { + "name": "teamId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 82, + "optional": false + }, + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "replayState", + "type": 83, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#Message" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "23cf7e0cf3fec1283b60fa15713506169bc9c079a08e124d1cb9733baca80b40", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 7, + 9, + 11, + 13, + 15, + 17 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "sections", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 8, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 12, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 14, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 16, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:system/message.data.message.source" + ], + "sources": [] + }, + { + "digest": "2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "apiVersion", + "type": 1, + "optional": false + }, + { + "name": "body", + "type": 2, + "optional": false + }, + { + "name": "endpoint", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "max_tokens", + "type": 3, + "optional": false + }, + { + "name": "messages", + "type": 4, + "optional": false + }, + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "tools", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 5, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 7, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 11, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "max_uses", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 12, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "web_search" + }, + { + "kind": "literal", + "value": "web_search_20250305" + } + ] + }, + "names": [ + "packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest" + ], + "sources": [ + "packages/web/web-search-deepseek/src/provider.ts" + ] + }, + { + "digest": "254dce209e735f9cb6f6b7aec0354712b1611759ec02af4d35a96f2081e666f6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "blocked" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 7, + "optional": false + }, + { + "name": "time", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "policy", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "ask" + }, + { + "kind": "literal", + "value": "never" + }, + { + "kind": "literal", + "value": "delegation" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "approval/policy" + } + ] + }, + "names": [ + "event:approval/policy" + ], + "sources": [] + }, + { + "digest": "26c879bdd130e8b8683a6ce588414fad2244783d6573ca399fa0de184a2b0bb1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "dispatch" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "26f3bb7529cfce1e3a0f1ededa365d8b426758ca0feeb0beabeee805f8bb8346", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "union", + "types": [ + 2, + 8, + 66, + 68 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 3, + "optional": false + }, + { + "name": "dt", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "time0", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 9, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 65, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 10, + 12, + 38, + 41, + 43, + 45, + 62 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 13, + "optional": false + }, + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 14, + 16, + 26, + 29, + 33, + 35 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 6, + "optional": false + }, + { + "name": "height", + "type": 6, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 6, + "optional": false + }, + { + "name": "width", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 30, + "optional": false + }, + { + "name": "isError", + "type": 31, + "optional": true + }, + { + "name": "toolCallId", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 13 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 39, + "optional": false + }, + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 15, + 25, + 28, + 32, + 34, + 36 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 46, + "optional": false + }, + { + "name": "replayState", + "type": 58, + "optional": true + }, + { + "name": "type", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 47, + 50, + 52, + 54, + 56 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 4, + "optional": false + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "offloadImages", + "type": 6, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 6, + "optional": true + }, + { + "name": "requestId", + "type": 4, + "optional": true + }, + { + "name": "status", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 59, + "optional": true + }, + { + "name": "response", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 60 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 63, + "optional": false + }, + { + "name": "usage", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 6, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 6, + "optional": true + }, + { + "name": "inputTokens", + "type": 6, + "optional": false + }, + { + "name": "outputTokens", + "type": 6, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 6, + "optional": true + }, + { + "name": "totalTokens", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 5, + "optional": false + }, + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "texts", + "type": 3, + "optional": false + }, + { + "name": "time0", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 5, + "optional": false + }, + { + "name": "index", + "type": 6, + "optional": false + }, + { + "name": "texts", + "type": 3, + "optional": false + }, + { + "name": "time0", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream", + "event:assistant/message.data.stream" + ], + "sources": [] + }, + { + "digest": "2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "model" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "file" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "afterSeconds", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "prompt", + "type": 2, + "optional": false + }, + { + "name": "scheduledAt", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "after" + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#AfterScheduleRecord" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 24, + "optional": true + }, + { + "name": "seq", + "type": 17, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 38, + "optional": true + }, + { + "name": "surfaceOp", + "type": 39, + "optional": false + }, + { + "name": "time", + "type": 17, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "meta", + "type": 34, + "optional": true + }, + { + "name": "step", + "type": 17, + "optional": false + }, + { + "name": "turn", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "reason", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 6, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "isError", + "type": 29, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 8 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "union", + "types": [ + 3, + 17, + 29, + 35, + 36, + 37 + ] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 34 + } + ] + }, + { + "kind": "array", + "element": 17 + }, + { + "kind": "union", + "types": [ + 40, + 41 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 17, + "optional": false + }, + { + "name": "op", + "type": 42, + "optional": false + }, + { + "name": "startSeq", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "tool/result" + } + ] + }, + "names": [ + "event:tool/result" + ], + "sources": [] + }, + { + "digest": "2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 19, + "optional": true + }, + { + "name": "seq", + "type": 13, + "optional": false + }, + { + "name": "time", + "type": 13, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 6, + 8, + 9 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "acceptedAt", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "operation", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "dispatch" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "operation", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "delete" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "operation", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "operation", + "type": 10, + "optional": false + }, + { + "name": "schedule", + "type": 11, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "union", + "types": [ + 12, + 15, + 17 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "afterSeconds", + "type": 13, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 14, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "after" + }, + { + "kind": "object", + "properties": [ + { + "name": "everySeconds", + "type": 13, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "every" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "at" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "schedule/change" + } + ] + }, + "names": [ + "event:schedule/change" + ], + "sources": [] + }, + { + "digest": "2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 2, + "optional": false + }, + { + "name": "cwd", + "type": 1, + "optional": true + }, + { + "name": "delegationDepth", + "type": 2, + "optional": true + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "isSeeded", + "type": 3, + "optional": false + }, + { + "name": "origin", + "type": 4, + "optional": true + }, + { + "name": "parentSession", + "type": 1, + "optional": true + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "subagent" + }, + { + "kind": "literal", + "value": 3 + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#SessionHeader" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 2, + "optional": false + }, + { + "name": "digest", + "type": 6, + "optional": true + }, + { + "name": "path", + "type": 6, + "optional": false + }, + { + "name": "scope", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[16].changes" + ], + "sources": [] + }, + { + "digest": "2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning-delta" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[2]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool/ptc-dispatch-start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "unavailable" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "step/start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "2ce7ef3b3daebf95815c7ae454a751d3e67ca7a22e2e0734fe2942df393bb66c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[6]", + "event:system/message.data.message.source[5]" + ], + "sources": [] + }, + { + "digest": "2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "max_uses", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "web_search" + }, + { + "kind": "literal", + "value": "web_search_20250305" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body.tools[0]" + ], + "sources": [ + "packages/web/web-search-deepseek/src/provider.ts" + ] + }, + { + "digest": "2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "fork" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "team-message" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "2f0aefb72ab453c4bf21a6687f436775d359dc6f8f10410fd4c0615b20bd9d76", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "header", + "type": 1, + "optional": false + }, + { + "name": "reason", + "type": 12, + "optional": false + }, + { + "name": "startsSeries", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 2, + "optional": true + }, + { + "name": "config", + "type": 4, + "optional": false + }, + { + "name": "tools", + "type": 8, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 3, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 6, + "optional": true + }, + { + "name": "stop", + "type": 7, + "optional": true + }, + { + "name": "temperature", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "array", + "element": 9 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "parameters", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 6, + "value": 11 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "series" + }, + { + "kind": "literal", + "value": "change" + }, + { + "kind": "literal", + "value": "initial" + } + ] + }, + "names": [ + "event:request/header.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + } + ] + }, + "names": [ + "packages/attachment/attachment/src/types.ts#ImageMediaType" + ], + "sources": [ + "packages/attachment/attachment/src/types.ts" + ] + }, + { + "digest": "2f90a7b3646fea3e677bd7b4000aa96f3b8964f107b614e204e11ad4051c24fc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[3]", + "event:system/message.data.message.source[2]" + ], + "sources": [] + }, + { + "digest": "2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "parentCallId", + "type": 2, + "optional": false + }, + { + "name": "rootCallId", + "type": 2, + "optional": false + }, + { + "name": "subCallId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/core/tools/src/types.ts#PtcDispatchStartEventData" + ], + "sources": [ + "packages/core/tools/src/types.ts" + ] + }, + { + "digest": "300341f890f7b9506a1749fff4fa5239d16ea1c63ff6b15851acb03c20f3b48d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 18, + 21, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 8, + "optional": false + }, + { + "name": "offloaded", + "type": 16, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "mediaType", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 15, + "optional": true + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 11, + 12, + 13, + 14 + ] + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 22, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 30, + 39, + 41, + 42, + 45, + 50, + 52, + 57, + 58, + 59, + 61, + 63, + 64, + 71, + 73, + 75, + 77, + 79, + 82, + 83 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 16, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 31, + "optional": false + }, + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 32 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 33, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 34, + 35, + 36 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 46, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "update", + "type": 16, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 47 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 53, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "sections", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 56 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 60, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 60, + "optional": false + }, + { + "name": "kind", + "type": 65, + "optional": false + }, + { + "name": "references", + "type": 66, + "optional": false + }, + { + "name": "version", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 67 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 9, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 68, + "optional": false + }, + { + "name": "compacted", + "type": 22, + "optional": false + }, + { + "name": "inputIndex", + "type": 9, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 9, + "optional": false + }, + { + "name": "omittedMessages", + "type": 9, + "optional": false + }, + { + "name": "originalMessages", + "type": 9, + "optional": false + }, + { + "name": "retainedMessages", + "type": 9, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 69 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 72, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 76, + "optional": false + }, + { + "name": "revision", + "type": 9, + "optional": false + }, + { + "name": "round", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 81, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted" + ], + "sources": [] + }, + { + "digest": "302b01ddddcbb3b16cfa3fba2a5d99f5082a55fbd9dc5c83a179a228b8a6a0ca", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 27, + "optional": false + }, + { + "name": "source", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 17, + 20, + 23, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 7, + "optional": false + }, + { + "name": "offloaded", + "type": 15, + "optional": true + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 8, + "optional": false + }, + { + "name": "height", + "type": 8, + "optional": false + }, + { + "name": "mediaType", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 14, + "optional": true + }, + { + "name": "width", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 10, + 11, + 12, + 13 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 8, + "optional": false + }, + { + "name": "width", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 8, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "isError", + "type": 21, + "optional": true + }, + { + "name": "toolCallId", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "union", + "types": [ + 29, + 34, + 36, + 38, + 40, + 42, + 44 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 30, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "sections", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 33 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#SystemMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 5, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "model", + "type": 3, + "optional": true + }, + { + "name": "provider", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "provider" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "fallback" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "packages/session/session-title/src/types.ts#SessionTitleSource" + ], + "sources": [ + "packages/session/session-title/src/types.ts" + ] + }, + { + "digest": "314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 16, + "optional": true + }, + { + "name": "seq", + "type": 9, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 84, + "optional": true + }, + { + "name": "surfaceOp", + "type": 85, + "optional": false + }, + { + "name": "time", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 88, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 18, + 21, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 8, + "optional": false + }, + { + "name": "offloaded", + "type": 16, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "mediaType", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 15, + "optional": true + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 11, + 12, + 13, + 14 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 22, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 30, + 39, + 41, + 42, + 45, + 50, + 52, + 57, + 58, + 59, + 61, + 63, + 64, + 71, + 73, + 75, + 77, + 79, + 82, + 83 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 16, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 31, + "optional": false + }, + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 32 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 33, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 34, + 35, + 36 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 46, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "update", + "type": 16, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 47 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 53, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "sections", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 56 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 60, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 60, + "optional": false + }, + { + "name": "kind", + "type": 65, + "optional": false + }, + { + "name": "references", + "type": 66, + "optional": false + }, + { + "name": "version", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 67 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 9, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 68, + "optional": false + }, + { + "name": "compacted", + "type": 22, + "optional": false + }, + { + "name": "inputIndex", + "type": 9, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 9, + "optional": false + }, + { + "name": "omittedMessages", + "type": 9, + "optional": false + }, + { + "name": "originalMessages", + "type": 9, + "optional": false + }, + { + "name": "retainedMessages", + "type": 9, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 69 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 72, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 76, + "optional": false + }, + { + "name": "revision", + "type": 9, + "optional": false + }, + { + "name": "round", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 81, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 9 + }, + { + "kind": "union", + "types": [ + 86, + 87 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 9, + "optional": false + }, + { + "name": "op", + "type": 35, + "optional": false + }, + { + "name": "startSeq", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user/message" + } + ] + }, + "names": [ + "event:user/message" + ], + "sources": [] + }, + { + "digest": "326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 1, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + } + ] + }, + "names": [ + "packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults" + ], + "sources": [ + "packages/llm/llm/src/call-config.ts" + ] + }, + { + "digest": "3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + } + ] + }, + "names": [ + "event:feedback/message-put.data.item.category", + "event:feedback/record.data.category" + ], + "sources": [] + }, + { + "digest": "335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 3, + "optional": false + }, + { + "name": "op", + "type": 4, + "optional": false + }, + { + "name": "startSeq", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "replace" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#SurfaceOp" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "resume" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "model/selection" + } + ] + }, + "names": [ + "event:model/selection" + ], + "sources": [] + }, + { + "digest": "356aad27134a0e31af67c994ff8b9e4b91acfb6c4917b3bc1f7a62bbf82794d5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 1, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "meta", + "type": 33, + "optional": true + }, + { + "name": "step", + "type": 16, + "optional": false + }, + { + "name": "turn", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 5, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "isError", + "type": 28, + "optional": true + }, + { + "name": "toolCallId", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 12, + 14, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 15, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "union", + "types": [ + 2, + 16, + 28, + 34, + 35, + 36 + ] + }, + { + "kind": "array", + "element": 33 + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 2, + "value": 33 + } + ] + } + ] + }, + "names": [ + "event:tool/result.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "36d6a9a871d949ea4f3edd919d81d66aa69218bebef38899d2a1282c39420a1f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "approval/policy" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 2, + "optional": true + }, + { + "name": "commandId", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "command/run" + } + ] + }, + "names": [ + "event:command/run" + ], + "sources": [] + }, + { + "digest": "374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 1, + "optional": false + }, + { + "name": "failure", + "type": 2, + "optional": false + }, + { + "name": "mode", + "type": 4, + "optional": false + }, + { + "name": "policyKey", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "retry", + "type": 1, + "optional": false + }, + { + "name": "retryId", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "offloadImages", + "type": 1, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 1, + "optional": true + }, + { + "name": "requestId", + "type": 3, + "optional": true + }, + { + "name": "status", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "always" + } + ] + }, + "names": [ + "event:llm/retry.data[1]" + ], + "sources": [ + "packages/llm/llm-retry/src/types.ts" + ] + }, + { + "digest": "378f90f9f6022a0991928a1eaf7991094ea1920fe89a9248358a1da106e1a970", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "approval/decided" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "contextWindow", + "type": 2, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "systemPromptUpdate", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "in-history" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "request/context" + } + ] + }, + "names": [ + "event:request/context" + ], + "sources": [] + }, + { + "digest": "383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "recall" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 1, + "optional": false + }, + { + "name": "dt", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "time0", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-chunks" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][2]" + ], + "sources": [ + "packages/llm/llm/src/assistant-stream.ts" + ] + }, + { + "digest": "390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "negative" + }, + { + "kind": "literal", + "value": "positive" + } + ] + }, + "names": [ + "packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating" + ], + "sources": [ + "packages/feedback/message-feedback/src/types.ts" + ] + }, + { + "digest": "3aa261c8516b5c955ed12080e6257a56cbe513f6c9f0ac9274c12e96c196ebca", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 1, + "optional": false + }, + { + "name": "maxTokens", + "type": 2, + "optional": true + }, + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "rawOutput", + "type": 3, + "optional": true + }, + { + "name": "shadowedRange", + "type": 27, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 28, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 2, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 1, + "optional": true + }, + { + "name": "summary", + "type": 3, + "optional": false + }, + { + "name": "usage", + "type": 29, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 12, + 14, + 24 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 6, + "optional": true + }, + { + "name": "toolCallId", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 15, + "optional": false + }, + { + "name": "offloaded", + "type": 22, + "optional": true + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": true + }, + { + "name": "originalDimensions", + "type": 21, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 18, + 19, + 20 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 25, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 2, + "optional": false + }, + { + "name": "start", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 2, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 2, + "optional": true + }, + { + "name": "inputTokens", + "type": 2, + "optional": false + }, + { + "name": "outputTokens", + "type": 2, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 2, + "optional": true + }, + { + "name": "totalTokens", + "type": 2, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:compaction/summary.data[1]" + ], + "sources": [] + }, + { + "digest": "3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 6 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 2, + "optional": false + }, + { + "name": "childId", + "type": 3, + "optional": false + }, + { + "name": "label", + "type": 3, + "optional": false + }, + { + "name": "mode", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "literal", + "value": 0 + }, + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 2, + "optional": false + }, + { + "name": "childId", + "type": 3, + "optional": false + }, + { + "name": "label", + "type": 3, + "optional": true + }, + { + "name": "mode", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "one-shot" + } + ] + }, + "names": [ + "packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent" + ], + "sources": [ + "packages/subagent/subagent/src/catalog.ts" + ] + }, + { + "digest": "3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "callId", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "tool/call" + } + ] + }, + "names": [ + "event:tool/call" + ], + "sources": [] + }, + { + "digest": "3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "normal" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:compaction/end.data.turn", + "event:compaction/start.data.turn", + "packages/core/session/src/types.ts#OptionalSessionSeq" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 2, + "optional": true + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 2, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "approval/asked" + } + ] + }, + "names": [ + "event:approval/asked" + ], + "sources": [] + }, + { + "digest": "3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "reasoning" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "allow", + "type": 1, + "optional": true + }, + { + "name": "deny", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/core/tools/src/index.ts#ToolRestriction" + ], + "sources": [ + "packages/core/tools/src/index.ts" + ] + }, + { + "digest": "3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 9, + "optional": false + }, + { + "name": "messageId", + "type": 10, + "optional": false + }, + { + "name": "note", + "type": 10, + "optional": true + }, + { + "name": "rating", + "type": 11, + "optional": false + }, + { + "name": "updatedAt", + "type": 9, + "optional": false + }, + { + "name": "version", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 12, + 13 + ] + }, + { + "kind": "literal", + "value": "negative" + }, + { + "kind": "literal", + "value": "positive" + } + ] + }, + "names": [ + "packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem" + ], + "sources": [ + "packages/feedback/message-feedback/src/types.ts" + ] + }, + { + "digest": "3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "request/header" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "next-step" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 1, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 1, + "optional": true + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:compaction/start.data" + ], + "sources": [ + "packages/compaction/compaction/src/types.ts" + ] + }, + { + "digest": "3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "messageId", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "feedback/message-delete" + } + ] + }, + "names": [ + "event:feedback/message-delete" + ], + "sources": [] + }, + { + "digest": "3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "image/jpeg" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 8, + "optional": false + }, + { + "name": "time", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "runId", + "type": 2, + "optional": false + }, + { + "name": "stopReason", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-workflow/run-end" + } + ] + }, + "names": [ + "event:tool-workflow/run-end" + ], + "sources": [] + }, + { + "digest": "4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "turn/end" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 24, + "optional": true + }, + { + "name": "seq", + "type": 17, + "optional": false + }, + { + "name": "time", + "type": 17, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "targetId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 9, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 6, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": "team/message/queued" + } + ] + }, + "names": [ + "event:team/message/queued" + ], + "sources": [] + }, + { + "digest": "44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "feedback/message-delete" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "subagent/catalog" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "step/start" + } + ] + }, + "names": [ + "event:step/start" + ], + "sources": [] + }, + { + "digest": "45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 1, + "optional": true + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "reason", + "type": 1, + "optional": true + }, + { + "name": "toolName", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:approval/asked.data" + ], + "sources": [ + "packages/interaction/user-approval/src/types.ts" + ] + }, + { + "digest": "477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "targets", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "imageIndexes", + "type": 3, + "optional": false + }, + { + "name": "seq", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:image/offload.data" + ], + "sources": [ + "packages/compaction/compaction-image-offload/src/projection.ts" + ] + }, + { + "digest": "478738df7e7d2b103b09fb937817a9302c81076809f2b341169e00a9419c5665", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 18, + 21, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 8, + "optional": false + }, + { + "name": "offloaded", + "type": 16, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "mediaType", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 15, + "optional": true + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 11, + 12, + 13, + 14 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 9, + "optional": false + }, + { + "name": "width", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 22, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "union", + "types": [ + 29, + 30, + 31 + ] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 33, + 42, + 44, + 45, + 48, + 53, + 55, + 60, + 61, + 62, + 64, + 66, + 67, + 74, + 76, + 78, + 80, + 82, + 85, + 86 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 16, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 34, + "optional": false + }, + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 35 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 36, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 37, + 38, + 39 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 46, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 49, + "optional": false + }, + { + "name": "form", + "type": 51, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "update", + "type": 16, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 50 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 56, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "sections", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 59 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 46, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 65, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 51, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 68, + "optional": false + }, + { + "name": "references", + "type": 69, + "optional": false + }, + { + "name": "version", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 70 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 9, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 71, + "optional": false + }, + { + "name": "compacted", + "type": 22, + "optional": false + }, + { + "name": "inputIndex", + "type": 9, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 9, + "optional": false + }, + { + "name": "omittedMessages", + "type": 9, + "optional": false + }, + { + "name": "originalMessages", + "type": 9, + "optional": false + }, + { + "name": "retainedMessages", + "type": 9, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 72 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 46, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 65, + "optional": false + }, + { + "name": "kind", + "type": 77, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "revision", + "type": 9, + "optional": false + }, + { + "name": "round", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 81, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 83, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 84, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "plugin", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:session/title-llm-request.data.messages" + ], + "sources": [] + }, + { + "digest": "47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "session-log-deepseek/delivery-accepted" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "retry", + "type": 2, + "optional": false + }, + { + "name": "retryId", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "llm/retry-started" + } + ] + }, + "names": [ + "event:llm/retry-started" + ], + "sources": [] + }, + { + "digest": "48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "messageId", + "type": 2, + "optional": false + }, + { + "name": "targetId", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "team/message/delivered" + } + ] + }, + "names": [ + "event:team/message/delivered" + ], + "sources": [] + }, + { + "digest": "4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "senderSessionId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource" + ], + "sources": [ + "packages/subagent/subagent/src/continuation-messages.ts" + ] + }, + { + "digest": "4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "llm/retry-started" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "tuple", + "elements": [ + { + "type": 1, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "max_uses", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "web_search" + }, + { + "kind": "literal", + "value": "web_search_20250305" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body.tools" + ], + "sources": [] + }, + { + "digest": "4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "status", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [ + "event:todo/write.data.todos" + ], + "sources": [] + }, + { + "digest": "4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + } + ] + }, + "names": [ + "event:turn/end.data.reason[1].reason[3]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "4c965666d5b42116945bc356087cd5e1fd549e6dece560785ed60511059a8283", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 12, + 14, + 16, + 19, + 24, + 26, + 31, + 32, + 34, + 35, + 36, + 38, + 47, + 49, + 51, + 53, + 55, + 58, + 59 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 2, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 3, + "optional": true + }, + { + "name": "changes", + "type": 4, + "optional": false + }, + { + "name": "form", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 6, + "optional": false + }, + { + "name": "digest", + "type": 3, + "optional": true + }, + { + "name": "path", + "type": 3, + "optional": false + }, + { + "name": "scope", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 3, + "optional": true + }, + { + "name": "kind", + "type": 15, + "optional": false + }, + { + "name": "rpcId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 3, + "optional": false + }, + { + "name": "form", + "type": 17, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "ruleId", + "type": 3, + "optional": false + }, + { + "name": "source", + "type": 3, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 20, + "optional": false + }, + { + "name": "form", + "type": 22, + "optional": false + }, + { + "name": "kind", + "type": 23, + "optional": false + }, + { + "name": "update", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 21 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 25, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 27, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + }, + { + "name": "sections", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 30 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 17, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 22, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "references", + "type": 40, + "optional": false + }, + { + "name": "version", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 41 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 42, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 43, + "optional": false + }, + { + "name": "compacted", + "type": 45, + "optional": false + }, + { + "name": "inputIndex", + "type": 42, + "optional": false + }, + { + "name": "label", + "type": 3, + "optional": false + }, + { + "name": "omittedBytes", + "type": 42, + "optional": false + }, + { + "name": "omittedMessages", + "type": 42, + "optional": false + }, + { + "name": "originalMessages", + "type": 42, + "optional": false + }, + { + "name": "retainedMessages", + "type": 42, + "optional": false + }, + { + "name": "sessionId", + "type": 3, + "optional": false + }, + { + "name": "truncated", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 42, + 44 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 17, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "senderSessionId", + "type": 3, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "senderSessionId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "revision", + "type": 42, + "optional": false + }, + { + "name": "round", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "messageId", + "type": 3, + "optional": false + }, + { + "name": "senderId", + "type": 3, + "optional": false + }, + { + "name": "senderName", + "type": 3, + "optional": false + }, + { + "name": "teamId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "replayState", + "type": 57, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 15, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#MessageSource" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/api/session-controller/src/types.ts#SessionRequestId", + "packages/attachment/attachment/src/brand.ts#AttachmentId", + "packages/compaction/compaction/src/brand.ts#CompactionId", + "packages/core/session/src/types.ts#SessionId", + "packages/experimental/agent-team/src/types.ts#TeamId", + "packages/experimental/agent-team/src/types.ts#TeamMessageId", + "packages/experimental/agent-team/src/types.ts#TeamTaskId", + "packages/feedback/message-feedback/src/types.ts#MessageFeedbackVersion", + "packages/goal/goal/src/types.ts#GoalId", + "packages/interaction/commands/src/brand.ts#CommandId", + "packages/interaction/user-approval/src/types.ts#ApprovalRequestId", + "packages/llm/llm-retry/src/brand.ts#RetryId", + "packages/llm/llm/src/brand.ts#MessageId", + "packages/llm/llm/src/brand.ts#ProviderRequestId", + "packages/llm/llm/src/brand.ts#ReasoningEffortId", + "packages/llm/llm/src/brand.ts#ToolCallId", + "packages/schedule/schedule/src/types.ts#ScheduleId", + "packages/session/session-title/src/index.ts#SessionTitleProviderId", + "packages/session/session-title/src/types.ts#SessionTitleProviderId", + "packages/webhook/webhook/src/brand.ts#WebhookDeliveryId", + "packages/webhook/webhook/src/brand.ts#WebhookRuleId", + "packages/webhook/webhook/src/brand.ts#WebhookSourceId", + "packages/workflow/workflow/src/types.ts#WorkflowRunId" + ], + "sources": [ + "packages/api/session-controller/src/types.ts", + "packages/attachment/attachment/src/brand.ts", + "packages/compaction/compaction/src/brand.ts", + "packages/core/session/src/types.ts", + "packages/experimental/agent-team/src/types.ts", + "packages/feedback/message-feedback/src/types.ts", + "packages/goal/goal/src/types.ts", + "packages/interaction/commands/src/brand.ts", + "packages/interaction/user-approval/src/types.ts", + "packages/llm/llm-retry/src/brand.ts", + "packages/llm/llm/src/brand.ts", + "packages/schedule/schedule/src/types.ts", + "packages/session/session-title/src/index.ts", + "packages/session/session-title/src/types.ts", + "packages/webhook/webhook/src/brand.ts", + "packages/workflow/workflow/src/types.ts" + ] + }, + { + "digest": "4de5e7644130ed715ef6b5a4d86a87b30dca4096d1a6683c66acf6f7809379c7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 27, + "optional": false + }, + { + "name": "source", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 17, + 20, + 23, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 7, + "optional": false + }, + { + "name": "offloaded", + "type": 15, + "optional": true + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 8, + "optional": false + }, + { + "name": "height", + "type": 8, + "optional": false + }, + { + "name": "mediaType", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 14, + "optional": true + }, + { + "name": "width", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 10, + 11, + 12, + 13 + ] + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 8, + "optional": false + }, + { + "name": "width", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 8, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "isError", + "type": 21, + "optional": true + }, + { + "name": "toolCallId", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 29, + 38, + 40, + 41, + 44, + 49, + 51, + 56, + 57, + 58, + 60, + 62, + 63, + 70, + 72, + 74, + 76, + 78, + 81, + 82 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 15, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 4, + "optional": true + }, + { + "name": "changes", + "type": 30, + "optional": false + }, + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 31 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 32, + "optional": false + }, + { + "name": "digest", + "type": 4, + "optional": true + }, + { + "name": "path", + "type": 4, + "optional": false + }, + { + "name": "scope", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 33, + 34, + 35 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 4, + "optional": true + }, + { + "name": "kind", + "type": 27, + "optional": false + }, + { + "name": "rpcId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 4, + "optional": false + }, + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "ruleId", + "type": 4, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 45, + "optional": false + }, + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "update", + "type": 15, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 46 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "sections", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 55 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + }, + { + "name": "references", + "type": 65, + "optional": false + }, + { + "name": "version", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 66 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 8, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 67, + "optional": false + }, + { + "name": "compacted", + "type": 21, + "optional": false + }, + { + "name": "inputIndex", + "type": 8, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": false + }, + { + "name": "omittedBytes", + "type": 8, + "optional": false + }, + { + "name": "omittedMessages", + "type": 8, + "optional": false + }, + { + "name": "originalMessages", + "type": 8, + "optional": false + }, + { + "name": "retainedMessages", + "type": 8, + "optional": false + }, + { + "name": "sessionId", + "type": 4, + "optional": false + }, + { + "name": "truncated", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 68 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "revision", + "type": 8, + "optional": false + }, + { + "name": "round", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 77, + "optional": false + }, + { + "name": "messageId", + "type": 4, + "optional": false + }, + { + "name": "senderId", + "type": 4, + "optional": false + }, + { + "name": "senderName", + "type": 4, + "optional": false + }, + { + "name": "teamId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "replayState", + "type": 80, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "plugin", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 27, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#UserMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "team/message/queued" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "text" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body.messages[0].content[0]", + "packages/llm/llm/src/types.ts#TextBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts", + "packages/web/web-search-deepseek/src/provider.ts" + ] + }, + { + "digest": "4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "senderSessionId", + "type": 3, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource" + ], + "sources": [ + "packages/subagent/subagent/src/continuation-messages.ts" + ] + }, + { + "digest": "4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "series" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 1, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 2, + "optional": false + }, + { + "name": "compacted", + "type": 4, + "optional": false + }, + { + "name": "inputIndex", + "type": 1, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 1, + "optional": false + }, + { + "name": "omittedMessages", + "type": 1, + "optional": false + }, + { + "name": "originalMessages", + "type": 1, + "optional": false + }, + { + "name": "retainedMessages", + "type": 1, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 1, + 3 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[15].references[0]" + ], + "sources": [ + "packages/context/session-reference/src/types.ts" + ] + }, + { + "digest": "4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 12, + "optional": true + }, + { + "name": "seq", + "type": 13, + "optional": false + }, + { + "name": "time", + "type": 13, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "member", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "context", + "type": 3, + "optional": false + }, + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "error", + "type": 6, + "optional": true + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "phase", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "fork" + }, + { + "kind": "literal", + "value": "fresh" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 8, + 9, + 10 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "literal", + "value": "provisioning" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "team/member" + } + ] + }, + "names": [ + "event:team/member" + ], + "sources": [] + }, + { + "digest": "50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "fork" + }, + { + "kind": "literal", + "value": "fresh" + } + ] + }, + "names": [ + "event:team/member.data.member.context" + ], + "sources": [] + }, + { + "digest": "511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "success" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 8, + "optional": false + }, + { + "name": "time", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "mode", + "type": 2, + "optional": false + }, + { + "name": "source", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "danger-full-access" + }, + { + "kind": "literal", + "value": "read-only" + }, + { + "kind": "literal", + "value": "workspace-write" + }, + { + "kind": "literal", + "value": "delegation" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "sandbox/mode" + } + ] + }, + "names": [ + "event:sandbox/mode" + ], + "sources": [] + }, + { + "digest": "51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "blockedBy", + "type": 1, + "optional": false + }, + { + "name": "description", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "ownerId", + "type": 2, + "optional": true + }, + { + "name": "revision", + "type": 3, + "optional": false + }, + { + "name": "status", + "type": 4, + "optional": false + }, + { + "name": "subject", + "type": 2, + "optional": false + }, + { + "name": "writeScopes", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 5, + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "deleted" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [ + "packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 9, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 3, + "optional": false + }, + { + "name": "failure", + "type": 4, + "optional": false + }, + { + "name": "maxRetries", + "type": 3, + "optional": false + }, + { + "name": "mode", + "type": 6, + "optional": false + }, + { + "name": "policyKey", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "retry", + "type": 3, + "optional": false + }, + { + "name": "retryId", + "type": 5, + "optional": false + }, + { + "name": "step", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 5, + "optional": false + }, + { + "name": "message", + "type": 5, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 5, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "normal" + }, + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 3, + "optional": false + }, + { + "name": "failure", + "type": 4, + "optional": false + }, + { + "name": "mode", + "type": 8, + "optional": false + }, + { + "name": "policyKey", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "retry", + "type": 3, + "optional": false + }, + { + "name": "retryId", + "type": 5, + "optional": false + }, + { + "name": "step", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "always" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "llm/retry" + } + ] + }, + "names": [ + "event:llm/retry" + ], + "sources": [] + }, + { + "digest": "529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 1, + "value": 2 + } + ] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 0, + 1, + 3, + 4, + 5, + 6 + ] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:tool/result.data.meta[5][0][6]", + "event:tool/result.data.meta[6]" + ], + "sources": [ + "packages/util/values/src/index.ts" + ] + }, + { + "digest": "530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "change" + }, + { + "kind": "literal", + "value": "initial" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "series" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#RequestHeaderReason" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "557e148d30b79ee48645850832b30c717d7c3b64641deb5d6133b8b4e91ee0b8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "agent-preset/selected" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + } + ] + }, + "names": [ + "event:turn/end.data.reason[5]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool/result" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 10, + 11 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 4, + "optional": true + }, + { + "name": "surfaceOp", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 3, + "optional": false + }, + { + "name": "op", + "type": 8, + "optional": false + }, + { + "name": "startSeq", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "surfaceOp", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "SessionEventEnvelope" + ], + "sources": [] + }, + { + "digest": "57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "stop" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 3, + 5, + 10, + 12 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 8, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 8, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 8, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#FinishReason" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "session/title-llm-request" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "image/png" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "text-delta" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5b232a9b9bfcc0fc6794dab7865bcf203a65785c5de5aa647a51228bff628413", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "after" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5b694f394d5e11609887a3ccfa82844935d49806c37e336b30be2186d649ab94", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "targetId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 7, + 9, + 11, + 13, + 24 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "isError", + "type": 4, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 14, + "optional": false + }, + { + "name": "offloaded", + "type": 22, + "optional": true + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "mediaType", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 21, + "optional": true + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 17, + 18, + 19, + 20 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 25, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + } + ] + }, + "names": [ + "packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "commandId", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sourceEventSeq", + "type": 5, + "optional": true + }, + { + "name": "text", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "literal", + "value": "success" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:command/done.data" + ], + "sources": [ + "packages/interaction/commands/src/types.ts" + ] + }, + { + "digest": "5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "resource-cost" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "preset", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "permission/preset" + } + ] + }, + "names": [ + "event:permission/preset" + ], + "sources": [] + }, + { + "digest": "5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "SessionEventEnvelope[39].sourceEventSeqs", + "SessionEventEnvelope[52].sourceEventSeqs", + "SessionEventEnvelope[55].sourceEventSeqs", + "event:assistant/attempt.data.stream[0][0].dt", + "event:assistant/attempt.data.stream[0][1].dt", + "event:assistant/attempt.data.stream[0][2].dt", + "event:compaction/prune.data.shadowedSeqs", + "event:compaction/summary.data[0].shadowedSeqs", + "event:compaction/summary.data[1].shadowedSeqs", + "event:image/offload.data.targets[0].imageIndexes", + "event:session/title-llm-request.data.messageSeqs", + "event:session/title.data.messageSeqs", + "event:system/message.sourceEventSeqs", + "event:tool/result.sourceEventSeqs", + "event:user/message.sourceEventSeqs" + ], + "sources": [] + }, + { + "digest": "5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-workflow/agent-end" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 1, + "optional": false + }, + { + "name": "childId", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 2, + "optional": true + }, + { + "name": "mode", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "one-shot" + }, + { + "kind": "literal", + "value": 0 + } + ] + }, + "names": [ + "event:subagent/catalog.data[0]" + ], + "sources": [] + }, + { + "digest": "5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "shadowedRange", + "type": 1, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 3, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 2, + "optional": false + }, + { + "name": "start", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 2 + } + ] + }, + "names": [ + "event:compaction/prune.data" + ], + "sources": [ + "packages/compaction/compaction/src/types.ts" + ] + }, + { + "digest": "5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 2, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "inherited", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "session/end-seed" + } + ] + }, + "names": [ + "event:session/end-seed" + ], + "sources": [] + }, + { + "digest": "5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "subagent/descriptor" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 1, + "optional": false + }, + { + "name": "message", + "type": 1, + "optional": false + }, + { + "name": "offloadImages", + "type": 2, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 2, + "optional": true + }, + { + "name": "requestId", + "type": 1, + "optional": true + }, + { + "name": "status", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#LlmFailure" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "childId", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 2, + "optional": false + }, + { + "name": "phase", + "type": 2, + "optional": true + }, + { + "name": "runId", + "type": 2, + "optional": false + }, + { + "name": "seq", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "tool-workflow/agent-start" + } + ] + }, + "names": [ + "event:tool-workflow/agent-start" + ], + "sources": [] + }, + { + "digest": "5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "label", + "type": 1, + "optional": true + }, + { + "name": "mode", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "version", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "one-shot" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData" + ], + "sources": [ + "packages/subagent/subagent/src/descriptor.ts" + ] + }, + { + "digest": "611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "llm/retry" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-call-chunks" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4, + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "block" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "literal", + "value": "edit" + }, + { + "kind": "literal", + "value": "pause" + }, + { + "kind": "literal", + "value": "resume" + } + ] + }, + "names": [ + "event:goal/change.data[0].operation" + ], + "sources": [] + }, + { + "digest": "62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "next-turn" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 18, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 90, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "inserted", + "type": 2, + "optional": false + }, + { + "name": "outcome", + "type": 86, + "optional": true + }, + { + "name": "removedCount", + "type": 11, + "optional": true + }, + { + "name": "start", + "type": 11, + "optional": false + }, + { + "name": "target", + "type": 87, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 20, + 23, + 26, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 18, + "optional": true + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 21, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 32, + 41, + 43, + 44, + 47, + 52, + 54, + 59, + 60, + 61, + 63, + 65, + 66, + 73, + 75, + 77, + 79, + 81, + 84, + 85 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 18, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 33, + "optional": false + }, + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 35, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 36, + 37, + 38 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 48, + "optional": false + }, + { + "name": "form", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "update", + "type": 18, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 49 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 55, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + }, + { + "name": "sections", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 58 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 64, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 67, + "optional": false + }, + { + "name": "references", + "type": 68, + "optional": false + }, + { + "name": "version", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 69 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 11, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 70, + "optional": false + }, + { + "name": "compacted", + "type": 24, + "optional": false + }, + { + "name": "inputIndex", + "type": 11, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 11, + "optional": false + }, + { + "name": "omittedMessages", + "type": 11, + "optional": false + }, + { + "name": "originalMessages", + "type": 11, + "optional": false + }, + { + "name": "retainedMessages", + "type": 11, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 11, + 71 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 64, + "optional": false + }, + { + "name": "kind", + "type": 76, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "revision", + "type": 11, + "optional": false + }, + { + "name": "round", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 82, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 83, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "plugin", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "canceled" + }, + { + "kind": "union", + "types": [ + 88, + 89 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + }, + { + "kind": "literal", + "value": "agent/inbox/spliced" + } + ] + }, + "names": [ + "event:agent/inbox/spliced" + ], + "sources": [] + }, + { + "digest": "647cb2e3aeb58e27d1d4d60011f208bb66dce257e8654193c533b47c4c22c253", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 1, + "optional": false + }, + { + "name": "index", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4, + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "block-start" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[0]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentModel", + "type": 1, + "optional": true + }, + { + "name": "agentProvider", + "type": 1, + "optional": true + }, + { + "name": "agentReasoningEffort", + "type": 1, + "optional": true + }, + { + "name": "label", + "type": 1, + "optional": false + }, + { + "name": "mode", + "type": 2, + "optional": false + }, + { + "name": "persona", + "type": 1, + "optional": true + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "toolFilter", + "type": 3, + "optional": true + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "object", + "properties": [ + { + "name": "allow", + "type": 4, + "optional": true + }, + { + "name": "deny", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 1 + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData" + ], + "sources": [ + "packages/subagent/subagent/src/descriptor.ts" + ] + }, + { + "digest": "658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "prompt", + "type": 1, + "optional": false + }, + { + "name": "scheduledAt", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "at" + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#AtScheduleRecord" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "context", + "type": 1, + "optional": false + }, + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "error", + "type": 4, + "optional": true + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "phase", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "fork" + }, + { + "kind": "literal", + "value": "fresh" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "literal", + "value": "provisioning" + } + ] + }, + "names": [ + "packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "everySeconds", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "prompt", + "type": 2, + "optional": false + }, + { + "name": "scheduledAt", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "every" + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#EveryScheduleRecord" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/skill/skill/src/index.ts#SkillInvocationSource" + ], + "sources": [ + "packages/skill/skill/src/index.ts" + ] + }, + { + "digest": "67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 1, + "optional": true + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 2, + "optional": true + }, + { + "name": "stop", + "type": 3, + "optional": true + }, + { + "name": "temperature", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 2 + } + ] + }, + "names": [ + "packages/llm/llm/src/call-config.ts#LlmCallConfig" + ], + "sources": [ + "packages/llm/llm/src/call-config.ts" + ] + }, + { + "digest": "68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "max-tokens" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "reasoning-chunks" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 2, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 17, + "optional": true + }, + { + "name": "seq", + "type": 10, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 47, + "optional": true + }, + { + "name": "surfaceOp", + "type": 48, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 10, + "optional": false + }, + { + "name": "turn", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 19, + 22, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 23, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "union", + "types": [ + 31, + 36, + 38, + 40, + 42, + 44, + 46 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + }, + { + "name": "sections", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 35 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 39, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 45, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "union", + "types": [ + 49, + 51 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 10, + "optional": false + }, + { + "name": "op", + "type": 50, + "optional": false + }, + { + "name": "startSeq", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "literal", + "value": "system/message" + } + ] + }, + "names": [ + "event:system/message" + ], + "sources": [] + }, + { + "digest": "69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "interrupted" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 1, + "optional": true + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "rpcId", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[10]" + ], + "sources": [ + "packages/api/session-controller/src/types.ts" + ] + }, + { + "digest": "6ab45ac76839722df912f3ba50f1c6b41f2d614bde11f1aabfae04117ccdc80d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "assistant/message" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "blockedReason", + "type": 1, + "optional": true + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "maxGoalRounds", + "type": 3, + "optional": false + }, + { + "name": "objective", + "type": 2, + "optional": false + }, + { + "name": "phase", + "type": 4, + "optional": false + }, + { + "name": "revision", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 5, + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "paused" + } + ] + }, + "names": [ + "packages/goal/goal/src/types.ts#GoalSnapshot" + ], + "sources": [ + "packages/goal/goal/src/types.ts" + ] + }, + { + "digest": "6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + } + ] + }, + "names": [ + "event:turn/end.data.reason[1].reason[1]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-calls" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + }, + { + "name": "reason", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:turn/end.data.reason[1].reason[2]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "feedback/message-put" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6d63f25a28b70801937a46b1058be5f52d4efbaf3516141470463ae469b59c23", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "parameters", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 2, + "value": 4 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "event:request/header.data.header.tools" + ], + "sources": [] + }, + { + "digest": "6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent-preset/selected.data" + ], + "sources": [ + "packages/preset/agent-presets/src/session.ts" + ] + }, + { + "digest": "6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "skill-catalog" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "reasoning-delta" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 1, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 2, + "optional": true + }, + { + "name": "changes", + "type": 3, + "optional": false + }, + { + "name": "form", + "type": 9, + "optional": false + }, + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 5, + "optional": false + }, + { + "name": "digest", + "type": 2, + "optional": true + }, + { + "name": "path", + "type": 2, + "optional": false + }, + { + "name": "scope", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + } + ] + }, + "names": [ + "packages/context/agent-instructions/src/state.ts#AgentInstructionSource" + ], + "sources": [ + "packages/context/agent-instructions/src/state.ts" + ] + }, + { + "digest": "6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "web/deepseek-search-llm-request" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "retry", + "type": 1, + "optional": false + }, + { + "name": "retryId", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData" + ], + "sources": [ + "packages/llm/llm-retry/src/types.ts" + ] + }, + { + "digest": "6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "snapshot" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "request/context" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "service-stability" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "replayState", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#ModelMessageSource" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 1, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 3, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning-chunks" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][1]" + ], + "sources": [ + "packages/llm/llm/src/assistant-stream.ts" + ] + }, + { + "digest": "72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "union", + "types": [ + 0, + 2, + 3, + 4, + 5, + 6 + ] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 1 + } + ] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:tool/result.data.meta[5]", + "event:tool/result.data.meta[5][0][5]" + ], + "sources": [] + }, + { + "digest": "7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "remove" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "757013fff5879d73d5753d8d1120faab56110e88ac3932485ab7e034d9e9ce61", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4, + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "literal", + "value": "tool-result" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ContentBlockType" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "7624ca28c61ca0eaa4f015140f3cea6e0c16cce2f2960fab5f531203d253903e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "create" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 23, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 9 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "cleared", + "type": 3, + "optional": false + }, + { + "name": "clearedAt", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "operation", + "type": 7, + "optional": false + }, + { + "name": "version", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "revision", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "goal/change" + }, + { + "kind": "literal", + "value": "clear" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "createdAt", + "type": 5, + "optional": false + }, + { + "name": "goal", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "operation", + "type": 17, + "optional": false + }, + { + "name": "roundsStarted", + "type": 5, + "optional": false + }, + { + "name": "updatedAt", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedReason", + "type": 11, + "optional": true + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "maxGoalRounds", + "type": 5, + "optional": false + }, + { + "name": "objective", + "type": 4, + "optional": false + }, + { + "name": "phase", + "type": 12, + "optional": false + }, + { + "name": "revision", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 4, + "optional": false + }, + { + "name": "message", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "paused" + }, + { + "kind": "union", + "types": [ + 15, + 18, + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "block" + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "edit" + }, + { + "kind": "literal", + "value": "pause" + }, + { + "kind": "literal", + "value": true + } + ] + }, + "names": [ + "event:goal/change" + ], + "sources": [] + }, + { + "digest": "76632533f67879dcb346fcae640540dbc89b2472b0bce88c59f7e48fc5c0e668", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "delegation" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "77b8491f946edfc8cc77ebae3ba49183759da31ba2dfa83d4c9e9e618c4b91d2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "interrupted", + "type": 1, + "optional": true + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 10, + "optional": false + }, + { + "name": "stream", + "type": 32, + "optional": false + }, + { + "name": "turn", + "type": 10, + "optional": false + }, + { + "name": "usage", + "type": 69, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 28, + "optional": false + }, + { + "name": "source", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 18, + 21, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 1, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 22, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "replayState", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 33 + }, + { + "kind": "union", + "types": [ + 34, + 38, + 71, + 73 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 35, + "optional": false + }, + { + "name": "dt", + "type": 36, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "time0", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 39, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 40, + 42, + 44, + 47, + 49, + 51, + 67 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "type", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 45, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 7, + 17, + 20, + 23, + 25, + 27 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 52, + "optional": false + }, + { + "name": "replayState", + "type": 64, + "optional": true + }, + { + "name": "type", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 53, + 56, + 58, + 60, + 62 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "message", + "type": 6, + "optional": false + }, + { + "name": "offloadImages", + "type": 10, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 10, + "optional": true + }, + { + "name": "requestId", + "type": 6, + "optional": true + }, + { + "name": "status", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 65, + "optional": true + }, + { + "name": "response", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 31 + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 68, + "optional": false + }, + { + "name": "usage", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 10, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 10, + "optional": true + }, + { + "name": "inputTokens", + "type": 10, + "optional": false + }, + { + "name": "outputTokens", + "type": 10, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 10, + "optional": true + }, + { + "name": "totalTokens", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 36, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "texts", + "type": 35, + "optional": false + }, + { + "name": "time0", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 36, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "texts", + "type": 35, + "optional": false + }, + { + "name": "time0", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 74, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [ + "event:assistant/message.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 2, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + } + ] + }, + "names": [ + "event:turn/end.data.reason[3]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "todos", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "status", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [ + "event:todo/write.data" + ], + "sources": [ + "packages/todo/tool-todo/src/types.ts" + ] + }, + { + "digest": "7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "session/title" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 1, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "surfaceOp", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 2, + "optional": false + }, + { + "name": "op", + "type": 6, + "optional": false + }, + { + "name": "startSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "SessionEventEnvelope[6]" + ], + "sources": [] + }, + { + "digest": "7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "messageId", + "type": 1, + "optional": false + }, + { + "name": "sessionId", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete" + ], + "sources": [ + "packages/feedback/message-feedback/src/types.ts" + ] + }, + { + "digest": "7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 8 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "cleared", + "type": 2, + "optional": false + }, + { + "name": "clearedAt", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + }, + { + "name": "operation", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "revision", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "goal/change" + }, + { + "kind": "literal", + "value": "clear" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "createdAt", + "type": 4, + "optional": false + }, + { + "name": "goal", + "type": 9, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + }, + { + "name": "operation", + "type": 16, + "optional": false + }, + { + "name": "roundsStarted", + "type": 4, + "optional": false + }, + { + "name": "updatedAt", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedReason", + "type": 10, + "optional": true + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "maxGoalRounds", + "type": 4, + "optional": false + }, + { + "name": "objective", + "type": 3, + "optional": false + }, + { + "name": "phase", + "type": 11, + "optional": false + }, + { + "name": "revision", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "paused" + }, + { + "kind": "union", + "types": [ + 14, + 17, + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "block" + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "literal", + "value": "edit" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "pause" + } + ] + }, + "names": [ + "packages/goal/goal/src/domain.ts#GoalChangeMeta" + ], + "sources": [ + "packages/goal/goal/src/domain.ts" + ] + }, + { + "digest": "7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 1, + "optional": true + }, + { + "name": "text", + "type": 9, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/feedback/command-feedback/src/types.ts#FeedbackRecord" + ], + "sources": [ + "packages/feedback/command-feedback/src/types.ts" + ] + }, + { + "digest": "7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "session-reference" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "7f5f2a8618c2ece530a18b1358b890fb57fb8c35705e47b66bff2296f8c6e889", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "parameters", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 1, + "value": 3 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ToolSchema" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "shadowedRange", + "type": 2, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 4, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 3, + "optional": false + }, + { + "name": "start", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "compaction/prune" + } + ] + }, + "names": [ + "event:compaction/prune" + ], + "sources": [] + }, + { + "digest": "7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "runId", + "type": 1, + "optional": false + }, + { + "name": "stopReason", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "error" + } + ] + }, + "names": [ + "packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData" + ], + "sources": [ + "packages/workflow/tool-workflow/src/types.ts" + ] + }, + { + "digest": "7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "revision", + "type": 3, + "optional": false + }, + { + "name": "round", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/goal/goal/src/domain.ts#GoalMessageSource" + ], + "sources": [ + "packages/goal/goal/src/domain.ts" + ] + }, + { + "digest": "811229eedcec57979dbadca7dbea832a59f8580cff30cb217fca5e2da16314bd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "allowed-once" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ReasoningBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "82470020b5bfcb1a843e2aa05602af7d37df99e82d01f015c7c589ba054fd89d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "agent-message" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "agent/inbox/spliced" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]" + ], + "sources": [ + "packages/skill/tool-skill/src/index.ts" + ] + }, + { + "digest": "83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 1, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/context/agent-instructions/src/render.ts#AgentInstructionChange" + ], + "sources": [ + "packages/context/agent-instructions/src/render.ts" + ] + }, + { + "digest": "8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "error" + } + ] + }, + "names": [ + "packages/workflow/workflow/src/types.ts#WorkflowStopReason" + ], + "sources": [ + "packages/workflow/workflow/src/types.ts" + ] + }, + { + "digest": "84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 1, + "optional": false + }, + { + "name": "message", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/goal/goal/src/types.ts#GoalBlockReason" + ], + "sources": [ + "packages/goal/goal/src/types.ts" + ] + }, + { + "digest": "85e1bd563d6c80c1f377f99f91103fec4e315148a7330f3b3dae7c2d04e33b01", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[7]", + "event:system/message.data.message.source[6]" + ], + "sources": [] + }, + { + "digest": "86cf1e44038cb8b11659863dd0efafe682e41b9c782265c1d50e0a687debfc60", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 7, + 65, + 67 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 2, + "optional": false + }, + { + "name": "dt", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "time0", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 8, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 11, + 37, + 40, + 42, + 44, + 61 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 12, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 15, + 25, + 28, + 32, + 34 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 29, + "optional": false + }, + { + "name": "isError", + "type": 30, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 12 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 38, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 14, + 24, + 27, + 31, + 33, + 35 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 45, + "optional": false + }, + { + "name": "replayState", + "type": 57, + "optional": true + }, + { + "name": "type", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 46, + 49, + 51, + 53, + 55 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "offloadImages", + "type": 5, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 5, + "optional": true + }, + { + "name": "requestId", + "type": 3, + "optional": true + }, + { + "name": "status", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 58, + "optional": true + }, + { + "name": "response", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 59 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 62, + "optional": false + }, + { + "name": "usage", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 5, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 5, + "optional": true + }, + { + "name": "inputTokens", + "type": 5, + "optional": false + }, + { + "name": "outputTokens", + "type": 5, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 5, + "optional": true + }, + { + "name": "totalTokens", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "texts", + "type": 2, + "optional": false + }, + { + "name": "time0", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "texts", + "type": 2, + "optional": false + }, + { + "name": "time0", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 68, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [ + "packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord" + ], + "sources": [ + "packages/llm/llm/src/assistant-stream.ts" + ] + }, + { + "digest": "86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "agentModel", + "type": 2, + "optional": true + }, + { + "name": "agentProvider", + "type": 2, + "optional": true + }, + { + "name": "agentReasoningEffort", + "type": 2, + "optional": true + }, + { + "name": "label", + "type": 2, + "optional": false + }, + { + "name": "mode", + "type": 3, + "optional": false + }, + { + "name": "persona", + "type": 2, + "optional": true + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "toolFilter", + "type": 4, + "optional": true + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "object", + "properties": [ + { + "name": "allow", + "type": 5, + "optional": true + }, + { + "name": "deny", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "label", + "type": 2, + "optional": true + }, + { + "name": "mode", + "type": 8, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "one-shot" + } + ] + }, + "names": [ + "packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData" + ], + "sources": [ + "packages/subagent/subagent/src/descriptor.ts" + ] + }, + { + "digest": "86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#ContextSnapshotSection" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "provisioning" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": true + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-delta" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[3]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 7, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "dialect", + "type": 2, + "optional": false + }, + { + "name": "handlerId", + "type": 5, + "optional": false + }, + { + "name": "matcher", + "type": 5, + "optional": true + }, + { + "name": "point", + "type": 5, + "optional": false + }, + { + "name": "turn", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "claude-code" + }, + { + "kind": "literal", + "value": "codex" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "hook/invoked" + } + ] + }, + "names": [ + "event:hook/invoked" + ], + "sources": [] + }, + { + "digest": "8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "preset", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:permission/preset.data" + ], + "sources": [ + "packages/interaction/permission-presets/src/index.ts" + ] + }, + { + "digest": "8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "decision", + "type": 1, + "optional": false + }, + { + "name": "durationMs", + "type": 2, + "optional": false + }, + { + "name": "exitCode", + "type": 2, + "optional": true + }, + { + "name": "handlerId", + "type": 1, + "optional": false + }, + { + "name": "point", + "type": 1, + "optional": false + }, + { + "name": "stderrSummary", + "type": 1, + "optional": true + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:hook/result.data" + ], + "sources": [ + "packages/hooks/hook-protocol/src/types.ts" + ] + }, + { + "digest": "8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "system" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "sessionFormatVersion", + "type": 1, + "optional": true + }, + { + "name": "sessionId", + "type": 2, + "optional": false + }, + { + "name": "throughSeq", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:session-log-deepseek/delivery-accepted.data" + ], + "sources": [ + "packages/session/session-log-deepseek/src/types.ts" + ] + }, + { + "digest": "8cdd3fdd295cee53035de16a1b23411716f75e9f994fe9510cac5d7fef605c76", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "command/done" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "8d2e5a3c4230e6ea6c0b5151f02241d0db02cd2551f2df1b6b9700cddcc0dca3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "error", + "type": 28, + "optional": true + }, + { + "name": "isError", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "parentCallId", + "type": 6, + "optional": false + }, + { + "name": "rootCallId", + "type": 6, + "optional": false + }, + { + "name": "subCallId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 8, + 10, + 12, + 14, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 5, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 15, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "reason", + "type": 6, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/core/tools/src/types.ts#PtcDispatchEventData" + ], + "sources": [ + "packages/core/tools/src/types.ts" + ] + }, + { + "digest": "8d6a011f3ef7096a4a922ef420458419ff6b20e1eaeece5d331db7585d2f08d6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "tuple", + "elements": [ + { + "type": 1, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 25, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 1, + 4, + 7, + 9, + 11, + 22 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 12, + "optional": false + }, + { + "name": "offloaded", + "type": 20, + "optional": true + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 13, + "optional": false + }, + { + "name": "height", + "type": 13, + "optional": false + }, + { + "name": "mediaType", + "type": 14, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 19, + "optional": true + }, + { + "name": "width", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 15, + 16, + 17, + 18 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 13, + "optional": false + }, + { + "name": "width", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 23, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 13, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + } + ] + }, + "names": [ + "event:tool/result.data.message.content" + ], + "sources": [] + }, + { + "digest": "8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 2, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "aborted" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "operation", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "dispatch" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "header", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 13, + "optional": false + }, + { + "name": "startsSeries", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 3, + "optional": true + }, + { + "name": "config", + "type": 5, + "optional": false + }, + { + "name": "tools", + "type": 9, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 6, + "optional": true + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 7, + "optional": true + }, + { + "name": "stop", + "type": 8, + "optional": true + }, + { + "name": "temperature", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "parameters", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 7, + "value": 12 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "union", + "types": [ + 14, + 15, + 16, + 17 + ] + }, + { + "kind": "literal", + "value": "initial" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "series" + }, + { + "kind": "literal", + "value": "change" + }, + { + "kind": "literal", + "value": "request/header" + } + ] + }, + "names": [ + "event:request/header" + ], + "sources": [] + }, + { + "digest": "8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "tuple", + "elements": [ + { + "type": 1, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body.messages[0].content" + ], + "sources": [] + }, + { + "digest": "904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action" + ], + "sources": [] + }, + { + "digest": "90c811b8c2668898515e69a24e82caffeb08517f9c7aa193867ff0380f3b535d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 1, + "optional": false + }, + { + "name": "index", + "type": 15, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 7, + 9, + 11, + 13, + 24 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 4, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 1 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 14, + "optional": false + }, + { + "name": "offloaded", + "type": 22, + "optional": true + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "mediaType", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 21, + "optional": true + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 17, + 18, + 19, + 20 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 25, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "block-end" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[4]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "max_tokens", + "type": 1, + "optional": false + }, + { + "name": "messages", + "type": 2, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "tools", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 3, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 5, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 10, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "max_uses", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "web_search" + }, + { + "kind": "literal", + "value": "web_search_20250305" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body" + ], + "sources": [ + "packages/web/web-search-deepseek/src/provider.ts" + ] + }, + { + "digest": "930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "allowed-once" + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "rejected" + }, + { + "kind": "literal", + "value": "unavailable" + } + ] + }, + "names": [ + "packages/interaction/user-approval/src/types.ts#ApprovalOutcome" + ], + "sources": [ + "packages/interaction/user-approval/src/types.ts" + ] + }, + { + "digest": "935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "web_search" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "primitive", + "type": "null" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][0].texts", + "event:assistant/attempt.data.stream[0][1].texts", + "event:assistant/attempt.data.stream[0][2].args", + "event:request/header.data.header.config.stop", + "event:subagent/descriptor.data[1].toolFilter.allow", + "event:subagent/descriptor.data[1].toolFilter.deny", + "event:team/task.data.task.blockedBy", + "event:team/task.data.task.writeScopes" + ], + "sources": [] + }, + { + "digest": "93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "outcome", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "allowed-once" + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "rejected" + }, + { + "kind": "literal", + "value": "unavailable" + } + ] + }, + "names": [ + "event:approval/decided.data" + ], + "sources": [ + "packages/interaction/user-approval/src/types.ts" + ] + }, + { + "digest": "93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": 0 + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "in_progress" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text-delta" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[1]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "95c0e88fcf0bafb2087f912ad9e2369de6ae6530cc0c4c2772c96205b57f7f60", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "assistant" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + } + ] + }, + "names": [ + "packages/core/agent/src/types.ts#InboxTarget" + ], + "sources": [ + "packages/core/agent/src/types.ts" + ] + }, + { + "digest": "9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "mode", + "type": 1, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "danger-full-access" + }, + { + "kind": "literal", + "value": "read-only" + }, + { + "kind": "literal", + "value": "workspace-write" + }, + { + "kind": "literal", + "value": "delegation" + } + ] + }, + "names": [ + "event:sandbox/mode.data" + ], + "sources": [ + "packages/sandbox/sandbox-policy/src/session-mode.ts" + ] + }, + { + "digest": "998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 1, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 3, + "optional": true + }, + { + "name": "surfaceOp", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 5, + 6 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 2, + "optional": false + }, + { + "name": "op", + "type": 7, + "optional": false + }, + { + "name": "startSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "SessionEventEnvelope[39]", + "SessionEventEnvelope[52]", + "SessionEventEnvelope[55]" + ], + "sources": [] + }, + { + "digest": "9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "role", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 2, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body.messages[0]" + ], + "sources": [ + "packages/web/web-search-deepseek/src/provider.ts" + ] + }, + { + "digest": "9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "childId", + "type": 1, + "optional": false + }, + { + "name": "label", + "type": 1, + "optional": false + }, + { + "name": "phase", + "type": 1, + "optional": true + }, + { + "name": "runId", + "type": 1, + "optional": false + }, + { + "name": "seq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData" + ], + "sources": [ + "packages/workflow/tool-workflow/src/types.ts" + ] + }, + { + "digest": "9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "image/offload" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-call-delta" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "other" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "9e07693fd7cd9babe0688c22c986e4d519ae1c0e40eeea13b2dc583bed2abc86", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "ask" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "imageIndexes", + "type": 2, + "optional": false + }, + { + "name": "seq", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:image/offload.data.targets" + ], + "sources": [] + }, + { + "digest": "9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 1, + "optional": false + }, + { + "name": "start", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:compaction/prune.data.shadowedRange", + "event:compaction/summary.data[0].shadowedRange", + "event:compaction/summary.data[1].shadowedRange" + ], + "sources": [ + "packages/compaction/compaction/src/types.ts" + ] + }, + { + "digest": "9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 1, + "optional": false + }, + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "ruleId", + "type": 1, + "optional": false + }, + { + "name": "source", + "type": 1, + "optional": false + }, + { + "name": "summary", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[19]" + ], + "sources": [ + "packages/webhook/webhook/src/types.ts" + ] + }, + { + "digest": "9fe0e77a7816b7fdb4b953ec0e2f0cd7bbd22c5de5c3567e612d1b20eb0992e6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 1, + "optional": false + }, + { + "name": "messageSeqs", + "type": 2, + "optional": false + }, + { + "name": "messages", + "type": 3, + "optional": false + }, + { + "name": "route", + "type": 89, + "optional": false + }, + { + "name": "system", + "type": 8, + "optional": false + }, + { + "name": "titleProvider", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 1 + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 8, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "union", + "types": [ + 7, + 10, + 20, + 23, + 26, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 8, + "optional": false + }, + { + "name": "id", + "type": 8, + "optional": false + }, + { + "name": "name", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 11, + "optional": false + }, + { + "name": "offloaded", + "type": 18, + "optional": true + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 8, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 8, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 21, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 8, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 8, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "union", + "types": [ + 31, + 32, + 33 + ] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 35, + 44, + 46, + 47, + 50, + 55, + 57, + 62, + 63, + 64, + 66, + 68, + 69, + 76, + 78, + 80, + 82, + 84, + 87, + 88 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 18, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 8, + "optional": true + }, + { + "name": "changes", + "type": 36, + "optional": false + }, + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 37 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 38, + "optional": false + }, + { + "name": "digest", + "type": 8, + "optional": true + }, + { + "name": "path", + "type": 8, + "optional": false + }, + { + "name": "scope", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 39, + 40, + 41 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 8, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 8, + "optional": true + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "rpcId", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 8, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "provider", + "type": 8, + "optional": false + }, + { + "name": "ruleId", + "type": 8, + "optional": false + }, + { + "name": "source", + "type": 8, + "optional": false + }, + { + "name": "summary", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 51, + "optional": false + }, + { + "name": "form", + "type": 53, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "update", + "type": 18, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 52 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 8, + "optional": false + }, + { + "name": "name", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "name", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 58, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + }, + { + "name": "sections", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 61 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 8, + "optional": false + }, + { + "name": "text", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + }, + { + "name": "summary", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 65, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 67, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 53, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 65, + "optional": false + }, + { + "name": "kind", + "type": 70, + "optional": false + }, + { + "name": "references", + "type": 71, + "optional": false + }, + { + "name": "version", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 72 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 1, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 73, + "optional": false + }, + { + "name": "compacted", + "type": 24, + "optional": false + }, + { + "name": "inputIndex", + "type": 1, + "optional": false + }, + { + "name": "label", + "type": 8, + "optional": false + }, + { + "name": "omittedBytes", + "type": 1, + "optional": false + }, + { + "name": "omittedMessages", + "type": 1, + "optional": false + }, + { + "name": "originalMessages", + "type": 1, + "optional": false + }, + { + "name": "retainedMessages", + "type": 1, + "optional": false + }, + { + "name": "sessionId", + "type": 8, + "optional": false + }, + { + "name": "truncated", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 1, + 74 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 77, + "optional": false + }, + { + "name": "senderSessionId", + "type": 8, + "optional": false + }, + { + "name": "summary", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 67, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "senderSessionId", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 8, + "optional": false + }, + { + "name": "kind", + "type": 81, + "optional": false + }, + { + "name": "revision", + "type": 1, + "optional": false + }, + { + "name": "round", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 83, + "optional": false + }, + { + "name": "messageId", + "type": 8, + "optional": false + }, + { + "name": "senderId", + "type": 8, + "optional": false + }, + { + "name": "senderName", + "type": 8, + "optional": false + }, + { + "name": "teamId", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 85, + "optional": false + }, + { + "name": "model", + "type": 8, + "optional": false + }, + { + "name": "provider", + "type": 8, + "optional": false + }, + { + "name": "replayState", + "type": 86, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "plugin", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 8, + "optional": false + }, + { + "name": "provider", + "type": 8, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData" + ], + "sources": [ + "packages/session/session-title-llm/src/index.ts" + ] + }, + { + "digest": "9ff2ad8dddb836f75e8f6197fff2371323dfc396c3c6fb667e6e0b42fda79a5c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 1, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 2, + "optional": false + }, + { + "name": "maxTokens", + "type": 3, + "optional": true + }, + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "rawOutput", + "type": 4, + "optional": false + }, + { + "name": "shadowedRange", + "type": 27, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 28, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 3, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 1, + "optional": true + }, + { + "name": "summary", + "type": 4, + "optional": false + }, + { + "name": "usage", + "type": 29, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 13, + 15, + 24 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "isError", + "type": 7, + "optional": true + }, + { + "name": "toolCallId", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 2, + "optional": true + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 25, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 3, + "optional": false + }, + { + "name": "start", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 3, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 3, + "optional": true + }, + { + "name": "inputTokens", + "type": 3, + "optional": false + }, + { + "name": "outputTokens", + "type": 3, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 3, + "optional": true + }, + { + "name": "totalTokens", + "type": 3, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:compaction/summary.data[0]" + ], + "sources": [] + }, + { + "digest": "a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": 2 + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "agent-preset/selected" + } + ] + }, + "names": [ + "event:agent-preset/selected" + ], + "sources": [] + }, + { + "digest": "a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 1, + "optional": false + }, + { + "name": "replayState", + "type": 15, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 7, + 9, + 11, + 13 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 4, + "optional": false + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "offloadImages", + "type": 5, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 5, + "optional": true + }, + { + "name": "requestId", + "type": 4, + "optional": true + }, + { + "name": "status", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 16, + "optional": true + }, + { + "name": "response", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 17 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "a2be0f0cb59f0d4a06557d45847d1938aced238baa77a6da416e590b8b958553", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "error" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "hook/result" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "workspace-write" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "task", + "type": 1, + "optional": false + }, + { + "name": "teamId", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedBy", + "type": 2, + "optional": false + }, + { + "name": "description", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "ownerId", + "type": 3, + "optional": true + }, + { + "name": "revision", + "type": 4, + "optional": false + }, + { + "name": "status", + "type": 5, + "optional": false + }, + { + "name": "subject", + "type": 3, + "optional": false + }, + { + "name": "writeScopes", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 6, + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "deleted" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + }, + { + "kind": "literal", + "value": 2 + } + ] + }, + "names": [ + "event:team/task.data" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "a5a8c15f08af1b0f26f40906e0797b6b0920fd01069e660becce35ab7fc48d77", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 3, + 5, + 10, + 23, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 8, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 8, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 8, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 11, + "optional": false + }, + { + "name": "reason", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 13, + 15, + 17, + 19, + 21 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 20, + "optional": false + }, + { + "name": "reason", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#TurnEndReason" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 5, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "allowedModels", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "subagent/model-selection-policy" + } + ] + }, + "names": [ + "event:subagent/model-selection-policy" + ], + "sources": [] + }, + { + "digest": "a6a195c1b4a906d953d24ab5864c9f1881d545460e080a51144adfc9cb058cfe", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "inserted", + "type": 1, + "optional": false + }, + { + "name": "outcome", + "type": 85, + "optional": true + }, + { + "name": "removedCount", + "type": 10, + "optional": true + }, + { + "name": "start", + "type": 10, + "optional": false + }, + { + "name": "target", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 19, + 22, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 23, + "optional": true + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 31, + 40, + 42, + 43, + 46, + 51, + 53, + 58, + 59, + 60, + 62, + 64, + 65, + 72, + 74, + 76, + 78, + 80, + 83, + 84 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 17, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 6, + "optional": true + }, + { + "name": "changes", + "type": 32, + "optional": false + }, + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 33 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 34, + "optional": false + }, + { + "name": "digest", + "type": 6, + "optional": true + }, + { + "name": "path", + "type": 6, + "optional": false + }, + { + "name": "scope", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 35, + 36, + 37 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 6, + "optional": true + }, + { + "name": "kind", + "type": 29, + "optional": false + }, + { + "name": "rpcId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 6, + "optional": false + }, + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "ruleId", + "type": 6, + "optional": false + }, + { + "name": "source", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 47, + "optional": false + }, + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "update", + "type": 17, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 48 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + }, + { + "name": "sections", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 57 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 66, + "optional": false + }, + { + "name": "references", + "type": 67, + "optional": false + }, + { + "name": "version", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 68 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 10, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 69, + "optional": false + }, + { + "name": "compacted", + "type": 23, + "optional": false + }, + { + "name": "inputIndex", + "type": 10, + "optional": false + }, + { + "name": "label", + "type": 6, + "optional": false + }, + { + "name": "omittedBytes", + "type": 10, + "optional": false + }, + { + "name": "omittedMessages", + "type": 10, + "optional": false + }, + { + "name": "originalMessages", + "type": 10, + "optional": false + }, + { + "name": "retainedMessages", + "type": 10, + "optional": false + }, + { + "name": "sessionId", + "type": 6, + "optional": false + }, + { + "name": "truncated", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 10, + 70 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 77, + "optional": false + }, + { + "name": "revision", + "type": 10, + "optional": false + }, + { + "name": "round", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "messageId", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 81, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "replayState", + "type": 82, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "plugin", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "canceled" + }, + { + "kind": "union", + "types": [ + 87, + 88 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data" + ], + "sources": [ + "packages/core/agent/src/types.ts" + ] + }, + { + "digest": "a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2 + ] + }, + { + "kind": "literal", + "value": "claude-code" + }, + { + "kind": "literal", + "value": "codex" + } + ] + }, + "names": [ + "packages/hooks/hook-protocol/src/types.ts#HookDialect" + ], + "sources": [ + "packages/hooks/hook-protocol/src/types.ts" + ] + }, + { + "digest": "a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "runId", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData" + ], + "sources": [ + "packages/workflow/tool-workflow/src/types.ts" + ] + }, + { + "digest": "a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "active", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "plan/mode" + } + ] + }, + "names": [ + "event:plan/mode" + ], + "sources": [] + }, + { + "digest": "a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "reason", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:tool/ptc-dispatch.data.error", + "event:tool/result.data.error" + ], + "sources": [ + "packages/core/session/src/types.ts", + "packages/core/tools/src/types.ts" + ] + }, + { + "digest": "a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 1, + "optional": true + }, + { + "name": "commandId", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "source", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "event:command/run.data" + ], + "sources": [ + "packages/interaction/commands/src/types.ts" + ] + }, + { + "digest": "a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "team/message/delivered" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "status", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [ + "packages/todo/tool-todo/src/types.ts#TodoItem" + ], + "sources": [ + "packages/todo/tool-todo/src/types.ts" + ] + }, + { + "digest": "aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "turn/start" + } + ] + }, + "names": [ + "event:turn/start" + ], + "sources": [] + }, + { + "digest": "aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "item", + "type": 1, + "optional": false + }, + { + "name": "sessionId", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 2, + "optional": true + }, + { + "name": "createdAt", + "type": 10, + "optional": false + }, + { + "name": "messageId", + "type": 11, + "optional": false + }, + { + "name": "note", + "type": 11, + "optional": true + }, + { + "name": "rating", + "type": 12, + "optional": false + }, + { + "name": "updatedAt", + "type": 10, + "optional": false + }, + { + "name": "version", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 13, + 14 + ] + }, + { + "kind": "literal", + "value": "negative" + }, + { + "kind": "literal", + "value": "positive" + } + ] + }, + "names": [ + "packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut" + ], + "sources": [ + "packages/feedback/message-feedback/src/types.ts" + ] + }, + { + "digest": "aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "primitive", + "type": "boolean" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "subagent" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]", + "event:turn/end.data.reason[4]" + ], + "sources": [ + "packages/core/session/src/types.ts", + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[17].entries" + ], + "sources": [] + }, + { + "digest": "acd36e1717d2b4ef9e98a8e6fac17ca1203f3f448e5bca51677f129a8f4999e2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "event:session/title-llm-request.data.messages[0].role" + ], + "sources": [] + }, + { + "digest": "ad22a5ca5bbaab2e1440779cd3648e85ddfc6f73b5207394eda699555cf31430", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "edit" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "legacy" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-workflow/agent-start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[0]", + "event:session/title.data.source[2]", + "event:turn/end.data.reason[1].reason[0]", + "packages/interaction/commands/src/types.ts#CommandSource" + ], + "sources": [ + "packages/core/session/src/types.ts", + "packages/interaction/commands/src/types.ts", + "packages/llm/llm/src/message.ts", + "packages/session/session-title/src/types.ts" + ] + }, + { + "digest": "ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 9, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 3, + "optional": false + }, + { + "name": "childId", + "type": 4, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": false + }, + { + "name": "mode", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "literal", + "value": 0 + }, + { + "kind": "object", + "properties": [ + { + "name": "childCreatedAt", + "type": 3, + "optional": false + }, + { + "name": "childId", + "type": 4, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": true + }, + { + "name": "mode", + "type": 8, + "optional": false + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "one-shot" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "subagent/catalog" + } + ] + }, + "names": [ + "event:subagent/catalog" + ], + "sources": [] + }, + { + "digest": "ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "permission/preset" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "aec150797b655c5f15ebb7a501454b0c208fbaccec9ace49d7de2171fc02f47d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "catalog" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "todo/write" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "aff60ef947c18b012644852bdd0d5bfe72065e061dd563787c76c646b4a10f6b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "claude-code" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "error", + "type": 2, + "optional": true + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "compaction/end" + } + ] + }, + "names": [ + "event:compaction/end" + ], + "sources": [] + }, + { + "digest": "b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": true + }, + { + "name": "originalDimensions", + "type": 8, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/attachment/attachment/src/types.ts#ImageAttachmentRef" + ], + "sources": [ + "packages/attachment/attachment/src/types.ts" + ] + }, + { + "digest": "b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "contextWindow", + "type": 1, + "optional": true + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "systemPromptUpdate", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "in-history" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#RequestContext" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks" + ], + "sources": [] + }, + { + "digest": "b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "member", + "type": 1, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "context", + "type": 2, + "optional": false + }, + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "error", + "type": 5, + "optional": true + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "phase", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "fork" + }, + { + "kind": "literal", + "value": "fresh" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "literal", + "value": "provisioning" + }, + { + "kind": "literal", + "value": 2 + } + ] + }, + "names": [ + "event:team/member.data" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "negative" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "targets", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "imageIndexes", + "type": 4, + "optional": false + }, + { + "name": "seq", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image/offload" + } + ] + }, + "names": [ + "event:image/offload" + ], + "sources": [] + }, + { + "digest": "b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "deleted" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [ + "packages/experimental/agent-team/src/types.ts#TeamTaskStatus" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 24, + "optional": true + }, + { + "name": "seq", + "type": 17, + "optional": false + }, + { + "name": "time", + "type": 17, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "error", + "type": 29, + "optional": true + }, + { + "name": "isError", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "parentCallId", + "type": 7, + "optional": false + }, + { + "name": "rootCallId", + "type": 7, + "optional": false + }, + { + "name": "subCallId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 9, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 6, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "reason", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool/ptc-dispatch" + } + ] + }, + "names": [ + "event:tool/ptc-dispatch" + ], + "sources": [] + }, + { + "digest": "b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "disposed" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b4d298d90c798fa4d1f5b030ce3ce8031c4c41beafdb05323bec8b2a06903b43", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[5]", + "event:system/message.data.message.source[4]" + ], + "sources": [] + }, + { + "digest": "b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 16, + "optional": true + }, + { + "name": "seq", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "item", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 3, + "optional": true + }, + { + "name": "createdAt", + "type": 11, + "optional": false + }, + { + "name": "messageId", + "type": 12, + "optional": false + }, + { + "name": "note", + "type": 12, + "optional": true + }, + { + "name": "rating", + "type": 13, + "optional": false + }, + { + "name": "updatedAt", + "type": 11, + "optional": false + }, + { + "name": "version", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "negative" + }, + { + "kind": "literal", + "value": "positive" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "feedback/message-put" + } + ] + }, + "names": [ + "event:feedback/message-put" + ], + "sources": [] + }, + { + "digest": "b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 11, + "optional": true + }, + { + "name": "seq", + "type": 12, + "optional": false + }, + { + "name": "time", + "type": 12, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "category", + "type": 2, + "optional": true + }, + { + "name": "text", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ] + }, + { + "kind": "literal", + "value": "instruction-following" + }, + { + "kind": "literal", + "value": "other" + }, + { + "kind": "literal", + "value": "product-interaction" + }, + { + "kind": "literal", + "value": "resource-cost" + }, + { + "kind": "literal", + "value": "security-privacy-permission" + }, + { + "kind": "literal", + "value": "service-stability" + }, + { + "kind": "literal", + "value": "task-result" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "feedback/record" + } + ] + }, + "names": [ + "event:feedback/record" + ], + "sources": [] + }, + { + "digest": "b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "messageSeqs", + "type": 1, + "optional": false + }, + { + "name": "source", + "type": 3, + "optional": false + }, + { + "name": "title", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 4, + 8, + 10 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 5, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": true + }, + { + "name": "provider", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "provider" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "fallback" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "packages/session/session-title/src/types.ts#SessionTitleEventData" + ], + "sources": [ + "packages/session/session-title/src/types.ts" + ] + }, + { + "digest": "b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "failed" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "team/task" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + } + ] + }, + "names": [ + "event:turn/end.data.reason[0]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "set" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 10, + "optional": true + }, + { + "name": "seq", + "type": 7, + "optional": false + }, + { + "name": "time", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 8 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "agentModel", + "type": 3, + "optional": true + }, + { + "name": "agentProvider", + "type": 3, + "optional": true + }, + { + "name": "agentReasoningEffort", + "type": 3, + "optional": true + }, + { + "name": "label", + "type": 3, + "optional": false + }, + { + "name": "mode", + "type": 4, + "optional": false + }, + { + "name": "persona", + "type": 3, + "optional": true + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "toolFilter", + "type": 5, + "optional": true + }, + { + "name": "version", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "continuable" + }, + { + "kind": "object", + "properties": [ + { + "name": "allow", + "type": 6, + "optional": true + }, + { + "name": "deny", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "label", + "type": 3, + "optional": true + }, + { + "name": "mode", + "type": 9, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "one-shot" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "subagent/descriptor" + } + ] + }, + "names": [ + "event:subagent/descriptor" + ], + "sources": [] + }, + { + "digest": "b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "goal" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + }, + { + "name": "model", + "type": 2, + "optional": true + }, + { + "name": "provider", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "provider" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:session/title.data.source[1]" + ], + "sources": [ + "packages/session/session-title/src/types.ts" + ] + }, + { + "digest": "b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "literal", + "value": "complete" + }, + { + "kind": "literal", + "value": "paused" + } + ] + }, + "names": [ + "packages/goal/goal/src/types.ts#GoalPhase" + ], + "sources": [ + "packages/goal/goal/src/types.ts" + ] + }, + { + "digest": "b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 1, + "optional": true + }, + { + "name": "path", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/fs/tool-present/src/types.ts#PresentedFile" + ], + "sources": [ + "packages/fs/tool-present/src/types.ts" + ] + }, + { + "digest": "b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "hook/invoked" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 9, + "optional": true + }, + { + "name": "seq", + "type": 10, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "todos", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "status", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "todo/write" + } + ] + }, + "names": [ + "event:todo/write" + ], + "sources": [] + }, + { + "digest": "b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "tuple", + "elements": [ + { + "type": 1, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "role", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 3, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request.data.body.messages" + ], + "sources": [] + }, + { + "digest": "ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:subagent/model-selection-policy.data.allowedModels" + ], + "sources": [] + }, + { + "digest": "bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 29, + "optional": true + }, + { + "name": "seq", + "type": 14, + "optional": false + }, + { + "name": "time", + "type": 14, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 5, + 7, + 9, + 11, + 16 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 12, + "optional": false + }, + { + "name": "kind", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 13, + "optional": false + }, + { + "name": "message", + "type": 13, + "optional": false + }, + { + "name": "offloadImages", + "type": 14, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 14, + "optional": true + }, + { + "name": "requestId", + "type": 13, + "optional": true + }, + { + "name": "status", + "type": 14, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 17, + "optional": false + }, + { + "name": "reason", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 19, + 21, + 23, + 25, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "reason", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "turn/end" + } + ] + }, + "names": [ + "event:turn/end" + ], + "sources": [] + }, + { + "digest": "babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 8, + "optional": true + }, + { + "name": "seq", + "type": 7, + "optional": false + }, + { + "name": "time", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "outcome", + "type": 2, + "optional": false + }, + { + "name": "runId", + "type": 6, + "optional": false + }, + { + "name": "seq", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 4, + 5 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "tool-workflow/agent-end" + } + ] + }, + "names": [ + "event:tool-workflow/agent-end" + ], + "sources": [] + }, + { + "digest": "bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 8, + "optional": true + }, + { + "name": "seq", + "type": 9, + "optional": false + }, + { + "name": "time", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "outcome", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "allowed-once" + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "rejected" + }, + { + "kind": "literal", + "value": "unavailable" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "approval/decided" + } + ] + }, + "names": [ + "event:approval/decided" + ], + "sources": [] + }, + { + "digest": "bb72d86bc9ef0b3908bfa57ef98ccccae24d67d945c9f6869ca3cb8577889e75", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "union", + "types": [ + 2, + 5, + 7, + 9, + 20, + 23 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 10, + "optional": false + }, + { + "name": "offloaded", + "type": 18, + "optional": true + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 11, + "optional": false + }, + { + "name": "width", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 21, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 0, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].content", + "event:agent/inbox/spliced.data.inserted[0].content[0][5].content", + "event:assistant/message.data.message.content", + "event:compaction/summary.data[0].rawOutput", + "event:compaction/summary.data[0].summary", + "event:compaction/summary.data[1].rawOutput", + "event:compaction/summary.data[1].summary", + "event:session/title-llm-request.data.messages[0].content", + "event:system/message.data.message.content", + "event:team/message/queued.data.message.content", + "event:tool/ptc-dispatch.data.content" + ], + "sources": [] + }, + { + "digest": "bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[8].replayState", + "event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks[0]", + "event:assistant/attempt.data.stream[0][3].chunk[6].replayState.response", + "event:request/header.data.header.tools[0].parameters.[value]", + "event:tool/ptc-dispatch-start.data.arguments", + "event:tool/ptc-dispatch.data.arguments" + ], + "sources": [] + }, + { + "digest": "bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 1, + "optional": false + }, + { + "name": "op", + "type": 2, + "optional": false + }, + { + "name": "startSeq", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "replace" + } + ] + }, + "names": [ + "SessionEventEnvelope[6].surfaceOp[1]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "finish" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "subagent-settled" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "outcome", + "type": 1, + "optional": false + }, + { + "name": "runId", + "type": 5, + "optional": false + }, + { + "name": "seq", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData" + ], + "sources": [ + "packages/workflow/tool-workflow/src/types.ts" + ] + }, + { + "digest": "c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 6 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 2, + "optional": false + }, + { + "name": "failure", + "type": 3, + "optional": false + }, + { + "name": "maxRetries", + "type": 2, + "optional": false + }, + { + "name": "mode", + "type": 5, + "optional": false + }, + { + "name": "policyKey", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "retry", + "type": 2, + "optional": false + }, + { + "name": "retryId", + "type": 4, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 4, + "optional": false + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "offloadImages", + "type": 2, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 2, + "optional": true + }, + { + "name": "requestId", + "type": 4, + "optional": true + }, + { + "name": "status", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "normal" + }, + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 2, + "optional": false + }, + { + "name": "failure", + "type": 3, + "optional": false + }, + { + "name": "mode", + "type": 7, + "optional": false + }, + { + "name": "policyKey", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "retry", + "type": 2, + "optional": false + }, + { + "name": "retryId", + "type": 4, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "always" + } + ] + }, + "names": [ + "packages/llm/llm-retry/src/types.ts#LlmRetryEventData" + ], + "sources": [ + "packages/llm/llm-retry/src/types.ts" + ] + }, + { + "digest": "c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ToolCallBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "runId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-workflow/run-start" + } + ] + }, + "names": [ + "event:tool-workflow/run-start" + ], + "sources": [] + }, + { + "digest": "c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "step/end" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "cancelled" + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "failed" + } + ] + }, + "names": [ + "packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome" + ], + "sources": [ + "packages/workflow/workflow/src/types.ts" + ] + }, + { + "digest": "c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "paused" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "c55a891c7aac496de6ee64c91c1fb65728c977314013033e42c863428aada854", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 1, + "optional": true + }, + { + "name": "config", + "type": 3, + "optional": false + }, + { + "name": "tools", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 2, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 5, + "optional": true + }, + { + "name": "stop", + "type": 6, + "optional": true + }, + { + "name": "temperature", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "array", + "element": 8 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "parameters", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 5, + "value": 10 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#EpochHeader" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool/call" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4, + 5, + 6 + ] + }, + { + "kind": "array", + "element": 0 + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 0 + } + ] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:tool/result.data.meta", + "packages/util/values/src/index.ts#JsonValue" + ], + "sources": [ + "packages/util/values/src/index.ts" + ] + }, + { + "digest": "c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[4].sections" + ], + "sources": [] + }, + { + "digest": "c7b24be059d34d08929593049a1a81eaa3855166aacfe9d7603c0bc8bb728d56", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 4, + 6, + 8, + 19, + 22 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 23, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 0 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ContentBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "stream", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 10, + 68, + 70 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 6, + "optional": false + }, + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 12, + 14, + 40, + 43, + 45, + 47, + 64 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 15, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 16, + 18, + 28, + 31, + 35, + 37 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 32, + "optional": false + }, + { + "name": "isError", + "type": 33, + "optional": true + }, + { + "name": "toolCallId", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 15 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 41, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 27, + 30, + 34, + 36, + 38 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 48, + "optional": false + }, + { + "name": "replayState", + "type": 60, + "optional": true + }, + { + "name": "type", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 49, + 52, + 54, + 56, + 58 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 2, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 2, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 61, + "optional": true + }, + { + "name": "response", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 62 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 65, + "optional": false + }, + { + "name": "usage", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 2, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 2, + "optional": true + }, + { + "name": "inputTokens", + "type": 2, + "optional": false + }, + { + "name": "outputTokens", + "type": 2, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 2, + "optional": true + }, + { + "name": "totalTokens", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "literal", + "value": "assistant/attempt" + } + ] + }, + "names": [ + "event:assistant/attempt" + ], + "sources": [] + }, + { + "digest": "c8e6f48878cc2a2f0dc59682280d81f407943fb503f32c64bf9ff3d9393c3eff", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "active" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "c93b6f51b399607349b4bcc66b58e848a44250ffc1e2537207bd092dfff94192", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 1, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 6, + 32, + 35, + 37, + 39, + 56 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 10, + 20, + 23, + 27, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 11, + "optional": false + }, + { + "name": "offloaded", + "type": 18, + "optional": true + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 21, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 24, + "optional": false + }, + { + "name": "isError", + "type": 25, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 33, + "optional": false + }, + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 19, + 22, + 26, + 28, + 30 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 40, + "optional": false + }, + { + "name": "replayState", + "type": 52, + "optional": true + }, + { + "name": "type", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 41, + 44, + 46, + 48, + 50 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "offloadImages", + "type": 4, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 4, + "optional": true + }, + { + "name": "requestId", + "type": 3, + "optional": true + }, + { + "name": "status", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 42, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 53, + "optional": true + }, + { + "name": "response", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 54 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 57, + "optional": false + }, + { + "name": "usage", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 4, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 4, + "optional": true + }, + { + "name": "inputTokens", + "type": 4, + "optional": false + }, + { + "name": "outputTokens", + "type": 4, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 4, + "optional": true + }, + { + "name": "totalTokens", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3]" + ], + "sources": [ + "packages/llm/llm/src/assistant-stream.ts" + ] + }, + { + "digest": "c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "feedback/record" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "sandbox/mode" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 1, + "optional": false + }, + { + "name": "error", + "type": 1, + "optional": true + }, + { + "name": "sourceCommandId", + "type": 1, + "optional": true + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 3, + 4 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:compaction/end.data" + ], + "sources": [ + "packages/compaction/compaction/src/types.ts" + ] + }, + { + "digest": "ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "operation", + "type": 1, + "optional": false + }, + { + "name": "schedule", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "union", + "types": [ + 3, + 7, + 9 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "afterSeconds", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "prompt", + "type": 5, + "optional": false + }, + { + "name": "scheduledAt", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "after" + }, + { + "kind": "object", + "properties": [ + { + "name": "everySeconds", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 8, + "optional": false + }, + { + "name": "prompt", + "type": 5, + "optional": false + }, + { + "name": "scheduledAt", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "every" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 10, + "optional": false + }, + { + "name": "prompt", + "type": 5, + "optional": false + }, + { + "name": "scheduledAt", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "at" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#ScheduleCreateChange" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "cbca49bde16b656d5b8fbe4a8a507769f7b594c6287782b809c03814941bc5e3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "block-start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "cd186c309e2bef305705e1d324139240f5e681f4f6a957d6a25b0225f65560df", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "approval/asked" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-workflow/run-start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "delayMs", + "type": 1, + "optional": false + }, + { + "name": "failure", + "type": 2, + "optional": false + }, + { + "name": "maxRetries", + "type": 1, + "optional": false + }, + { + "name": "mode", + "type": 4, + "optional": false + }, + { + "name": "policyKey", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "retry", + "type": 1, + "optional": false + }, + { + "name": "retryId", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "offloadImages", + "type": 1, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 1, + "optional": true + }, + { + "name": "requestId", + "type": 3, + "optional": true + }, + { + "name": "status", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "normal" + } + ] + }, + "names": [ + "event:llm/retry.data[0]" + ], + "sources": [ + "packages/llm/llm-retry/src/types.ts" + ] + }, + { + "digest": "cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 15, + "optional": true + }, + { + "name": "seq", + "type": 4, + "optional": false + }, + { + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "apiVersion", + "type": 2, + "optional": false + }, + { + "name": "body", + "type": 3, + "optional": false + }, + { + "name": "endpoint", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "max_tokens", + "type": 4, + "optional": false + }, + { + "name": "messages", + "type": 5, + "optional": false + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "tools", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 6, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "tuple", + "elements": [ + { + "type": 8, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "tuple", + "elements": [ + { + "type": 12, + "optional": false, + "rest": false + } + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "max_uses", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 13, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "web_search" + }, + { + "kind": "literal", + "value": "web_search_20250305" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "web/deepseek-search-llm-request" + } + ] + }, + "names": [ + "event:web/deepseek-search-llm-request" + ], + "sources": [] + }, + { + "digest": "cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "cleared", + "type": 1, + "optional": false + }, + { + "name": "clearedAt", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 4, + "optional": false + }, + { + "name": "operation", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "revision", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "goal/change" + }, + { + "kind": "literal", + "value": "clear" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/goal/goal/src/domain.ts#GoalClearChangeMeta" + ], + "sources": [ + "packages/goal/goal/src/domain.ts" + ] + }, + { + "digest": "d0fbb0ca1bbba059830826f33f801da1aced35a2504376d61e020bdfec8d50c0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "delete" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "one-shot" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "d3e447062a2847dad847dad5168a9508d92c484363dfc76fd82605aa7bd46285", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 4, + 6, + 11, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 8, + "optional": false + }, + { + "name": "message", + "type": 8, + "optional": false + }, + { + "name": "offloadImages", + "type": 9, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 9, + "optional": true + }, + { + "name": "requestId", + "type": 8, + "optional": true + }, + { + "name": "status", + "type": 9, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + }, + { + "name": "reason", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 14, + 16, + 18, + 20, + 22 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 21, + "optional": false + }, + { + "name": "reason", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + } + ] + }, + "names": [ + "event:turn/end.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "d4e4d575abeb4b72d616dc65c17ac0eaa943cc135609395044c38d5afcb10e31", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "canceled" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 12, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "task", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 4, + "optional": false + }, + { + "name": "version", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "blockedBy", + "type": 3, + "optional": false + }, + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "ownerId", + "type": 4, + "optional": true + }, + { + "name": "revision", + "type": 5, + "optional": false + }, + { + "name": "status", + "type": 6, + "optional": false + }, + { + "name": "subject", + "type": 4, + "optional": false + }, + { + "name": "writeScopes", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 7, + 8, + 9, + 10 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "deleted" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "team/task" + } + ] + }, + "names": [ + "event:team/task" + ], + "sources": [] + }, + { + "digest": "d61574d68558c5a184429e70b04da393dd5460bf5cc3ddef814546e659bd5127", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "isError", + "type": 24, + "optional": true + }, + { + "name": "toolCallId", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 0, + 3, + 6, + 8, + 10, + 21 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 11, + "optional": false + }, + { + "name": "offloaded", + "type": 19, + "optional": true + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 12, + "optional": false + }, + { + "name": "height", + "type": 12, + "optional": false + }, + { + "name": "mediaType", + "type": 13, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 18, + "optional": true + }, + { + "name": "width", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 14, + 15, + 16, + 17 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 12, + "optional": false + }, + { + "name": "width", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 22, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ToolResultBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "sessionFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "sessionId", + "type": 3, + "optional": false + }, + { + "name": "throughSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "session-log-deepseek/delivery-accepted" + } + ] + }, + "names": [ + "event:session-log-deepseek/delivery-accepted" + ], + "sources": [] + }, + { + "digest": "d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "fallback" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 5, + 7 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "afterSeconds", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 4, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "after" + }, + { + "kind": "object", + "properties": [ + { + "name": "everySeconds", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 6, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "every" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 8, + "optional": false + }, + { + "name": "prompt", + "type": 3, + "optional": false + }, + { + "name": "scheduledAt", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "at" + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#ScheduleRecord" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "d9196086e41e4dd5c2ce87f5c25529c8112a1731d258cf0728747d41a9ee3241", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "complete" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#ToolMessageSource" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": true + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "webhook" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 6, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "union", + "types": [ + 4, + 5 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "compaction/start" + } + ] + }, + "names": [ + "event:compaction/start" + ], + "sources": [] + }, + { + "digest": "dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "hook" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "fresh" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "dda6e111a8ccfc12f6e742e977a1a4e3549e8c03732a5ff6c8d7c3d4bcb7a412", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[2]", + "event:system/message.data.message.source[1]" + ], + "sources": [] + }, + { + "digest": "de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "user/message" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "image/gif" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "positive" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 3, + "optional": false + }, + { + "name": "compacted", + "type": 5, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 6, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 6, + "optional": false + }, + { + "name": "truncated", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 2, + 4 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[15].references" + ], + "sources": [] + }, + { + "digest": "dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "active" + }, + { + "kind": "literal", + "value": "failed" + }, + { + "kind": "literal", + "value": "provisioning" + } + ] + }, + "names": [ + "packages/experimental/agent-team/src/types.ts#TeamMemberPhase" + ], + "sources": [ + "packages/experimental/agent-team/src/types.ts" + ] + }, + { + "digest": "e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 3, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "step/end" + } + ] + }, + "names": [ + "event:step/end" + ], + "sources": [] + }, + { + "digest": "e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 19, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 91, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 2, + "optional": false + }, + { + "name": "messageSeqs", + "type": 3, + "optional": false + }, + { + "name": "messages", + "type": 4, + "optional": false + }, + { + "name": "route", + "type": 90, + "optional": false + }, + { + "name": "system", + "type": 9, + "optional": false + }, + { + "name": "titleProvider", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 9, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 11, + 21, + 24, + 27, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 9, + "optional": false + }, + { + "name": "id", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 12, + "optional": false + }, + { + "name": "offloaded", + "type": 19, + "optional": true + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 9, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 13, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": true + }, + { + "name": "originalDimensions", + "type": 18, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 14, + 15, + 16, + 17 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 22, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 9, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "isError", + "type": 25, + "optional": true + }, + { + "name": "toolCallId", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "union", + "types": [ + 32, + 33, + 34 + ] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 36, + 45, + 47, + 48, + 51, + 56, + 58, + 63, + 64, + 65, + 67, + 69, + 70, + 77, + 79, + 81, + 83, + 85, + 88, + 89 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 19, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 9, + "optional": true + }, + { + "name": "changes", + "type": 37, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 38 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 39, + "optional": false + }, + { + "name": "digest", + "type": 9, + "optional": true + }, + { + "name": "path", + "type": 9, + "optional": false + }, + { + "name": "scope", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 40, + 41, + 42 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 9, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 9, + "optional": true + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "rpcId", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 9, + "optional": false + }, + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "provider", + "type": 9, + "optional": false + }, + { + "name": "ruleId", + "type": 9, + "optional": false + }, + { + "name": "source", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 52, + "optional": false + }, + { + "name": "form", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "update", + "type": 19, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 53 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 9, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "name", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + }, + { + "name": "sections", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "array", + "element": 62 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 9, + "optional": false + }, + { + "name": "text", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 54, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "references", + "type": 72, + "optional": false + }, + { + "name": "version", + "type": 76, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 73 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 74, + "optional": false + }, + { + "name": "compacted", + "type": 25, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 9, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 9, + "optional": false + }, + { + "name": "truncated", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 75 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 49, + "optional": false + }, + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "senderSessionId", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 80, + "optional": false + }, + { + "name": "senderSessionId", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 9, + "optional": false + }, + { + "name": "kind", + "type": 82, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 84, + "optional": false + }, + { + "name": "messageId", + "type": 9, + "optional": false + }, + { + "name": "senderId", + "type": 9, + "optional": false + }, + { + "name": "senderName", + "type": 9, + "optional": false + }, + { + "name": "teamId", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 86, + "optional": false + }, + { + "name": "model", + "type": 9, + "optional": false + }, + { + "name": "provider", + "type": 9, + "optional": false + }, + { + "name": "replayState", + "type": 87, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "plugin", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 9, + "optional": false + }, + { + "name": "provider", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session/title-llm-request" + } + ] + }, + "names": [ + "event:session/title-llm-request" + ], + "sources": [] + }, + { + "digest": "e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 5, + 7, + 8 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "acceptedAt", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "operation", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "dispatch" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "operation", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "delete" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "operation", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "operation", + "type": 9, + "optional": false + }, + { + "name": "schedule", + "type": 10, + "optional": false + }, + { + "name": "version", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "create" + }, + { + "kind": "union", + "types": [ + 11, + 14, + 16 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "afterSeconds", + "type": 12, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + }, + { + "name": "prompt", + "type": 2, + "optional": false + }, + { + "name": "scheduledAt", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "after" + }, + { + "kind": "object", + "properties": [ + { + "name": "everySeconds", + "type": 12, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 15, + "optional": false + }, + { + "name": "prompt", + "type": 2, + "optional": false + }, + { + "name": "scheduledAt", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "every" + }, + { + "kind": "object", + "properties": [ + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 17, + "optional": false + }, + { + "name": "prompt", + "type": 2, + "optional": false + }, + { + "name": "scheduledAt", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "at" + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#ScheduleChange" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "e2d0367e5716bc188435e51718ebff8ce873190625fa93b1c5331102d98758fa", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "compaction/start" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "provider" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "ignorable", + "type": 1, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "SessionEventEnvelope[0]", + "SessionEventEnvelope[10]", + "SessionEventEnvelope[11]", + "SessionEventEnvelope[12]", + "SessionEventEnvelope[13]", + "SessionEventEnvelope[14]", + "SessionEventEnvelope[15]", + "SessionEventEnvelope[16]", + "SessionEventEnvelope[17]", + "SessionEventEnvelope[18]", + "SessionEventEnvelope[19]", + "SessionEventEnvelope[1]", + "SessionEventEnvelope[20]", + "SessionEventEnvelope[21]", + "SessionEventEnvelope[22]", + "SessionEventEnvelope[23]", + "SessionEventEnvelope[24]", + "SessionEventEnvelope[25]", + "SessionEventEnvelope[26]", + "SessionEventEnvelope[27]", + "SessionEventEnvelope[28]", + "SessionEventEnvelope[29]", + "SessionEventEnvelope[2]", + "SessionEventEnvelope[30]", + "SessionEventEnvelope[31]", + "SessionEventEnvelope[32]", + "SessionEventEnvelope[33]", + "SessionEventEnvelope[34]", + "SessionEventEnvelope[35]", + "SessionEventEnvelope[36]", + "SessionEventEnvelope[37]", + "SessionEventEnvelope[38]", + "SessionEventEnvelope[3]", + "SessionEventEnvelope[40]", + "SessionEventEnvelope[41]", + "SessionEventEnvelope[42]", + "SessionEventEnvelope[43]", + "SessionEventEnvelope[44]", + "SessionEventEnvelope[45]", + "SessionEventEnvelope[46]", + "SessionEventEnvelope[47]", + "SessionEventEnvelope[48]", + "SessionEventEnvelope[49]", + "SessionEventEnvelope[4]", + "SessionEventEnvelope[50]", + "SessionEventEnvelope[51]", + "SessionEventEnvelope[53]", + "SessionEventEnvelope[54]", + "SessionEventEnvelope[56]", + "SessionEventEnvelope[5]", + "SessionEventEnvelope[7]", + "SessionEventEnvelope[8]", + "SessionEventEnvelope[9]" + ], + "sources": [] + }, + { + "digest": "e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "session" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "every" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e438a9d4fb883b3e4a8d9fc8913aa1550ed50eb384bfbf943100a5605b537498", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "append" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "callId", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:tool/call.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "instruction-following" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e50b0a3ed8e6c80b672e4f855c91984f03b5c3fdd5d475bf171171f391a86c83", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 27, + "optional": false + }, + { + "name": "source", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 7, + 9, + 11, + 13, + 24 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "isError", + "type": 4, + "optional": true + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 14, + "optional": false + }, + { + "name": "offloaded", + "type": 22, + "optional": true + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "mediaType", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 21, + "optional": true + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 17, + 18, + 19, + 20 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 25, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 29, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 30, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#AssistantMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts" + ] + }, + { + "digest": "e5244812c495a80c2e78ba2c2690dca5f6b58ea8d3fe5531ff94a6f9ac5e5d66", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-result" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e5d3828df1ec3e2a66879de0659e0f4866d9cfffc00825ee731a66f8a0c03d98", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "continuable" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "acceptedAt", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "operation", + "type": 2, + "optional": false + }, + { + "name": "version", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "dispatch" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange" + ], + "sources": [ + "packages/schedule/schedule/src/types.ts" + ] + }, + { + "digest": "e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "parent" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e654d28d1e6c471147310d2fba396d00969cfe6ed9022626d3f2c2312e0b1cbb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "plugin" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 1, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 3, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][0]" + ], + "sources": [ + "packages/llm/llm/src/assistant-stream.ts" + ] + }, + { + "digest": "e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 3, + "optional": false + }, + { + "name": "time", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "decision", + "type": 2, + "optional": false + }, + { + "name": "durationMs", + "type": 3, + "optional": false + }, + { + "name": "exitCode", + "type": 3, + "optional": true + }, + { + "name": "handlerId", + "type": 2, + "optional": false + }, + { + "name": "point", + "type": 2, + "optional": false + }, + { + "name": "stderrSummary", + "type": 2, + "optional": true + }, + { + "name": "turn", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "hook/result" + } + ] + }, + "names": [ + "event:hook/result" + ], + "sources": [] + }, + { + "digest": "e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "initial" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e7e154d47d5fbc5366330fb4dade1f108c6dfe4335044d21ded14b7bf1dce084", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "clear" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e7e8f1318170b8284f16ab45a557afd4675c96071c0f2a456636481dab20b427", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "deleted" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e8d26e6993445743e6c4342c31b284c7d8f5574369abdd6021183af1a6b3538f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "plugin", + "type": 3, + "optional": false + }, + { + "name": "sections", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plugin" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:agent/inbox/spliced.data.inserted[0].source[4]", + "event:system/message.data.message.source[3]" + ], + "sources": [] + }, + { + "digest": "e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "notice" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "e95f957154b2b1b58692af53d4131180b6dd19e2264869f876dbaa959991494e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "assistant/attempt" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + } + ] + }, + "names": [ + "event:turn/end.data.reason[1].reason[4]" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "image/webp" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "parentCallId", + "type": 3, + "optional": false + }, + { + "name": "rootCallId", + "type": 3, + "optional": false + }, + { + "name": "subCallId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool/ptc-dispatch-start" + } + ] + }, + "names": [ + "event:tool/ptc-dispatch-start" + ], + "sources": [] + }, + { + "digest": "eefbea819caeeea91ccb02dfafc16c68dd7f961cf9c1b2be25a2084509cf5c5a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "block-end" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:step/end.data", + "event:step/start.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "ef4f00923b9edbae15c7ef05320280bf61147ca17146cf59690359bfd5e5da45", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "compaction/summary" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "task-result" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [ + "packages/api/session-controller/src/types.ts#ModelSelection" + ], + "sources": [ + "packages/api/session-controller/src/types.ts" + ] + }, + { + "digest": "f1996af2602e6f62b5ab179ca5c4af00d8753938b74cc6ef102de09e99e74a7e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "command/run" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/attachment/attachment/src/types.ts#FileAttachmentRef" + ], + "sources": [ + "packages/attachment/attachment/src/types.ts" + ] + }, + { + "digest": "f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 1, + "optional": false + }, + { + "name": "usage", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 3, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 3, + "optional": true + }, + { + "name": "inputTokens", + "type": 3, + "optional": false + }, + { + "name": "outputTokens", + "type": 3, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 3, + "optional": true + }, + { + "name": "totalTokens", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:assistant/attempt.data.stream[0][3].chunk[5]" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "file" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#FileBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "in-history" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#SystemPromptUpdate" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "references", + "type": 3, + "optional": false + }, + { + "name": "version", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 5, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 6, + "optional": false + }, + { + "name": "compacted", + "type": 8, + "optional": false + }, + { + "name": "inputIndex", + "type": 5, + "optional": false + }, + { + "name": "label", + "type": 9, + "optional": false + }, + { + "name": "omittedBytes", + "type": 5, + "optional": false + }, + { + "name": "omittedMessages", + "type": 5, + "optional": false + }, + { + "name": "originalMessages", + "type": 5, + "optional": false + }, + { + "name": "retainedMessages", + "type": 5, + "optional": false + }, + { + "name": "sessionId", + "type": 9, + "optional": false + }, + { + "name": "truncated", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 5, + 7 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [ + "packages/context/session-reference/src/types.ts#SessionReferenceSource" + ], + "sources": [ + "packages/context/session-reference/src/types.ts" + ] + }, + { + "digest": "f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "plan/mode" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "replace" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 32 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 4, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": false + }, + { + "name": "shadowedRange", + "type": 29, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 30, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 11, + 13, + 15, + 17, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "isError", + "type": 9, + "optional": true + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 4, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 5, + "optional": false + }, + { + "name": "start", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 5, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 5, + "optional": true + }, + { + "name": "inputTokens", + "type": 5, + "optional": false + }, + { + "name": "outputTokens", + "type": 5, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 5, + "optional": true + }, + { + "name": "totalTokens", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": true + }, + { + "name": "shadowedRange", + "type": 29, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 30, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compaction/summary" + } + ] + }, + "names": [ + "event:compaction/summary" + ], + "sources": [] + }, + { + "digest": "f789af5ab844827eb5a4f357c0afae1eeed108c6c22d8ca1a56e586b349a7c85", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "change" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": 1 + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "event:turn/start.data" + ], + "sources": [ + "packages/core/session/src/types.ts" + ] + }, + { + "digest": "f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "danger-full-access" + }, + { + "kind": "literal", + "value": "read-only" + }, + { + "kind": "literal", + "value": "workspace-write" + } + ] + }, + "names": [ + "packages/sandbox/sandbox/src/index.ts#SandboxMode" + ], + "sources": [ + "packages/sandbox/sandbox/src/index.ts" + ] + }, + { + "digest": "fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "rejected" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool/ptc-dispatch" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "image" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fbd2c74b346a1595b376139c587fadd23e4a21acc9c0abce342975b6cfc60986", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "agent-instructions" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 1, + "optional": false + }, + { + "name": "form", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + }, + { + "name": "update", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "literal", + "value": true + } + ] + }, + "names": [ + "packages/skill/tool-skill/src/index.ts#SkillCatalogSource" + ], + "sources": [ + "packages/skill/tool-skill/src/index.ts" + ] + }, + { + "digest": "fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3 + ] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "literal", + "value": "in_progress" + }, + { + "kind": "literal", + "value": "pending" + } + ] + }, + "names": [ + "event:todo/write.data.todos[0].status" + ], + "sources": [] + }, + { + "digest": "fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-workflow/run-end" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "feb329074f0206ecc06d8a1aa0a0b3e2f47fd27524ba020fbc849ba63e938896", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 31 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 3, + "optional": false + }, + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "rawOutput", + "type": 5, + "optional": false + }, + { + "name": "shadowedRange", + "type": 28, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 29, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 4, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "summary", + "type": 5, + "optional": false + }, + { + "name": "usage", + "type": 30, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "union", + "types": [ + 7, + 10, + 12, + 14, + 16, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "isError", + "type": 8, + "optional": true + }, + { + "name": "toolCallId", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool-result" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 3, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 4, + "optional": false + }, + { + "name": "start", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 4, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 4, + "optional": true + }, + { + "name": "inputTokens", + "type": 4, + "optional": false + }, + { + "name": "outputTokens", + "type": 4, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 4, + "optional": true + }, + { + "name": "totalTokens", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "rawOutput", + "type": 5, + "optional": true + }, + { + "name": "shadowedRange", + "type": 28, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 29, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 4, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "summary", + "type": 5, + "optional": false + }, + { + "name": "usage", + "type": 30, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [ + "event:compaction/summary.data" + ], + "sources": [] + }, + { + "digest": "fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 1, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 1, + "optional": true + }, + { + "name": "inputTokens", + "type": 1, + "optional": false + }, + { + "name": "outputTokens", + "type": 1, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 1, + "optional": true + }, + { + "name": "totalTokens", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#TokenUsage" + ], + "sources": [ + "packages/llm/llm/src/types.ts" + ] + }, + { + "digest": "fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "instructions" + } + ] + }, + "names": [], + "sources": [] + } + ] +} diff --git a/docs/persistence-changes/historical-formats/v3.zh.md b/docs/persistence-changes/historical-formats/v3.zh.md new file mode 100644 index 0000000000..b49cbf23a9 --- /dev/null +++ b/docs/persistence-changes/historical-formats/v3.zh.md @@ -0,0 +1,5634 @@ +--- +description: "完整的 Session V3 持久化类型、来源证据与物理编码参考。" +kind: persistence-format +--- + +# Session V3 持久化格式 + +[English](v3.md) | 中文 + +## 概述 + +查阅 PR #4320 中 V4 写入器变更之前捕获的 V3 持久化类型。系统提示词使用 surface 消息,替换端点使用 `startSeq` / `endSeq`,surface 事件具有显式位置。本快照保留该 V3 检查点的完整声明目录。 + +## 目录 + +- [来源证据](#evidence) +- [格式特征](#characteristics) +- [机器声明](#declaration) +- [完整 schema](#schema) +- [验证与限制](#verification) +- [开发备注](#dev-note) + +----- + + +## 来源证据 + +来源为 `release/session-log-v4` 上 PR #4320 的初始源码树,由日期为 2026-09-16、标题为 `chore(session): initialize V4 release integration PR` 的空提交记录。它包含写入器版本为 3 的 master 源码树,尚未包含 V4 源码变更。目录新鲜度检查通过后,V3 归档命令在写入器推进前捕获了该目录。此检查点既不是 PR 最终源码树,也不是新的产品发布;[发布状态参考](../../session-format-status.zh.md)负责发布证据。 + +提取的声明来自 `packages/core/session/src/types.ts`、`packages/session/session-persistence-jsonl/src/format.ts`,以及所有第一方 `SessionEventMap` 声明合并及其可达类型。下方源码位置指向该捕获的源码树,不包含行号。 + + +## 格式特征 + +以下事实描述所选检查点。下方生成的表格保留精确的字段类型与可选性。 + +- `SessionHeader.version` 解析为字面量 3。逻辑与物理 header 均要求 `isSeeded`;物理 header 没有 `seedLength`。 +- `system/message`、`user/message`、`assistant/message` 和 `tool/result` 要求 `surfaceOp`。替换端点为 `startSeq` 与 `endSeq`;Assistant 消息不携带 `sourceEventSeqs`。 +- Assistant 流仍内嵌在 message 或 attempt 事件中。系统提示词文本属于 `system/message`,PTC 分派事件使用 `tool/ptc-dispatch-start` 和 `tool/ptc-dispatch`。 + +[V3 codec](../../../packages/session/session-format-v2-to-v3/src/codec.ts)负责规范事件编码与来源事件范围编码。[V2 到 V3 规范](../../../packages/session/session-format-v2-to-v3/README.zh.md#v2-to-v3-specification)定义历史转换,其[原生 V3 准入规则](../../../packages/session/session-format-v2-to-v3/README.zh.md#native-v3-admission)区分扩展处理与历史来源验证。 + +对于已继承的 V3 Session,最后一个携带 `data.inherited: true` 的 `session/end-seed` 事件以其序号位置标识继承切点。物理 `sourceEventSeqs` 可以使用范围编码;逻辑 schema 保留展开后的数值数组。 + + +## 机器声明 + +[Schema 目录](v3.schema.json)。 + +```yaml persistence-format +schemaVersion: 1 +sessionFormatVersion: 3 +source: + pullRequest: 4320 +roots: + "SessionHeader": 2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03 + "JsonlHeaderLine": 18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f + "SessionEventEnvelope": 5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc + "event:agent-preset/selected": a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b + "event:agent/inbox/spliced": 646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f + "event:approval/asked": 3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1 + "event:approval/decided": bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3 + "event:approval/policy": 26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78 + "event:assistant/attempt": c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e + "event:assistant/message": 1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d + "event:command/done": 15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff + "event:command/run": 37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006 + "event:compaction/end": b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d + "event:compaction/prune": 7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04 + "event:compaction/start": db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965 + "event:compaction/summary": f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59 + "event:deliverables/presented": 13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176 + "event:feedback/message-delete": 3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796 + "event:feedback/message-put": b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf + "event:feedback/record": b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8 + "event:goal/change": 763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d + "event:hook/invoked": 8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0 + "event:hook/result": e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4 + "event:image/offload": b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e + "event:llm/retry": 525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336 + "event:llm/retry-started": 48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3 + "event:model/selection": 35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc + "event:permission/preset": 5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b + "event:plan/mode": a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f + "event:request/context": 37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf + "event:request/header": 8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489 + "event:sandbox/mode": 516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415 + "event:schedule/change": 2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42 + "event:session-log-deepseek/delivery-accepted": d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9 + "event:session/end-seed": 5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e + "event:session/title": 1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5 + "event:session/title-llm-request": e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d + "event:step/end": e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05 + "event:step/start": 4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986 + "event:subagent/catalog": ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871 + "event:subagent/descriptor": b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5 + "event:subagent/model-selection-policy": a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc + "event:system/message": 69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae + "event:team/member": 4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc + "event:team/message/delivered": 48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb + "event:team/message/queued": 443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4 + "event:team/task": d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a + "event:todo/write": b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26 + "event:tool-workflow/agent-end": babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7 + "event:tool-workflow/agent-start": 5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627 + "event:tool-workflow/run-end": 42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f + "event:tool-workflow/run-start": c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058 + "event:tool/call": 3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48 + "event:tool/ptc-dispatch": b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c + "event:tool/ptc-dispatch-start": ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93 + "event:tool/result": 29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2 + "event:turn/end": bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b + "event:turn/start": aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8 + "event:user/message": 314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578 + "event:web/deepseek-search-llm-request": cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331 +``` + + + + +## 完整 schema + +[完整机器目录](v3.schema.json)包含 60 个根类型和 467 种可达类型。摘要包含所有引用字段;源码名称和路径描述所选的历史源码树。 + +### 持久化类型指纹 + +| 根类型 | 类别 | SHA-256 | 已解析类型 | +|---|---|---|---| +| `SessionHeader` | header | `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` | [`packages/core/session/src/types.ts#SessionHeader`](#persistence-type-packagescoresessionsrctypestssessionheader) | +| `JsonlHeaderLine` | header | `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` | [`packages/session/session-persistence-jsonl/src/format.ts#HeaderLine`](#persistence-type-packagessessionsession-persistence-jsonlsrcformattsheaderline) | +| `SessionEventEnvelope` | envelope | `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` | [`SessionEventEnvelope`](#persistence-type-sessioneventenvelope) | +| `event:agent-preset/selected` | event | `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` | [`event:agent-preset/selected`](#persistence-type-eventagent-presetselected) | +| `event:agent/inbox/spliced` | event | `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` | [`event:agent/inbox/spliced`](#persistence-type-eventagentinboxspliced) | +| `event:approval/asked` | event | `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` | [`event:approval/asked`](#persistence-type-eventapprovalasked) | +| `event:approval/decided` | event | `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` | [`event:approval/decided`](#persistence-type-eventapprovaldecided) | +| `event:approval/policy` | event | `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` | [`event:approval/policy`](#persistence-type-eventapprovalpolicy) | +| `event:assistant/attempt` | event | `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` | [`event:assistant/attempt`](#persistence-type-eventassistantattempt) | +| `event:assistant/message` | event | `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` | [`event:assistant/message`](#persistence-type-eventassistantmessage) | +| `event:command/done` | event | `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` | [`event:command/done`](#persistence-type-eventcommanddone) | +| `event:command/run` | event | `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` | [`event:command/run`](#persistence-type-eventcommandrun) | +| `event:compaction/end` | event | `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` | [`event:compaction/end`](#persistence-type-eventcompactionend) | +| `event:compaction/prune` | event | `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` | [`event:compaction/prune`](#persistence-type-eventcompactionprune) | +| `event:compaction/start` | event | `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` | [`event:compaction/start`](#persistence-type-eventcompactionstart) | +| `event:compaction/summary` | event | `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` | [`event:compaction/summary`](#persistence-type-eventcompactionsummary) | +| `event:deliverables/presented` | event | `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` | [`event:deliverables/presented`](#persistence-type-eventdeliverablespresented) | +| `event:feedback/message-delete` | event | `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` | [`event:feedback/message-delete`](#persistence-type-eventfeedbackmessage-delete) | +| `event:feedback/message-put` | event | `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` | [`event:feedback/message-put`](#persistence-type-eventfeedbackmessage-put) | +| `event:feedback/record` | event | `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` | [`event:feedback/record`](#persistence-type-eventfeedbackrecord) | +| `event:goal/change` | event | `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` | [`event:goal/change`](#persistence-type-eventgoalchange) | +| `event:hook/invoked` | event | `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` | [`event:hook/invoked`](#persistence-type-eventhookinvoked) | +| `event:hook/result` | event | `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` | [`event:hook/result`](#persistence-type-eventhookresult) | +| `event:image/offload` | event | `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` | [`event:image/offload`](#persistence-type-eventimageoffload) | +| `event:llm/retry` | event | `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` | [`event:llm/retry`](#persistence-type-eventllmretry) | +| `event:llm/retry-started` | event | `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` | [`event:llm/retry-started`](#persistence-type-eventllmretry-started) | +| `event:model/selection` | event | `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` | [`event:model/selection`](#persistence-type-eventmodelselection) | +| `event:permission/preset` | event | `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` | [`event:permission/preset`](#persistence-type-eventpermissionpreset) | +| `event:plan/mode` | event | `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` | [`event:plan/mode`](#persistence-type-eventplanmode) | +| `event:request/context` | event | `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` | [`event:request/context`](#persistence-type-eventrequestcontext) | +| `event:request/header` | event | `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` | [`event:request/header`](#persistence-type-eventrequestheader) | +| `event:sandbox/mode` | event | `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` | [`event:sandbox/mode`](#persistence-type-eventsandboxmode) | +| `event:schedule/change` | event | `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` | [`event:schedule/change`](#persistence-type-eventschedulechange) | +| `event:session-log-deepseek/delivery-accepted` | event | `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` | [`event:session-log-deepseek/delivery-accepted`](#persistence-type-eventsession-log-deepseekdelivery-accepted) | +| `event:session/end-seed` | event | `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` | [`event:session/end-seed`](#persistence-type-eventsessionend-seed) | +| `event:session/title` | event | `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` | [`event:session/title`](#persistence-type-eventsessiontitle) | +| `event:session/title-llm-request` | event | `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` | [`event:session/title-llm-request`](#persistence-type-eventsessiontitle-llm-request) | +| `event:step/end` | event | `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` | [`event:step/end`](#persistence-type-eventstepend) | +| `event:step/start` | event | `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` | [`event:step/start`](#persistence-type-eventstepstart) | +| `event:subagent/catalog` | event | `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` | [`event:subagent/catalog`](#persistence-type-eventsubagentcatalog) | +| `event:subagent/descriptor` | event | `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` | [`event:subagent/descriptor`](#persistence-type-eventsubagentdescriptor) | +| `event:subagent/model-selection-policy` | event | `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` | [`event:subagent/model-selection-policy`](#persistence-type-eventsubagentmodel-selection-policy) | +| `event:system/message` | event | `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` | [`event:system/message`](#persistence-type-eventsystemmessage) | +| `event:team/member` | event | `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` | [`event:team/member`](#persistence-type-eventteammember) | +| `event:team/message/delivered` | event | `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` | [`event:team/message/delivered`](#persistence-type-eventteammessagedelivered) | +| `event:team/message/queued` | event | `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` | [`event:team/message/queued`](#persistence-type-eventteammessagequeued) | +| `event:team/task` | event | `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` | [`event:team/task`](#persistence-type-eventteamtask) | +| `event:todo/write` | event | `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` | [`event:todo/write`](#persistence-type-eventtodowrite) | +| `event:tool-workflow/agent-end` | event | `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` | [`event:tool-workflow/agent-end`](#persistence-type-eventtool-workflowagent-end) | +| `event:tool-workflow/agent-start` | event | `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` | [`event:tool-workflow/agent-start`](#persistence-type-eventtool-workflowagent-start) | +| `event:tool-workflow/run-end` | event | `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` | [`event:tool-workflow/run-end`](#persistence-type-eventtool-workflowrun-end) | +| `event:tool-workflow/run-start` | event | `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` | [`event:tool-workflow/run-start`](#persistence-type-eventtool-workflowrun-start) | +| `event:tool/call` | event | `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` | [`event:tool/call`](#persistence-type-eventtoolcall) | +| `event:tool/ptc-dispatch` | event | `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` | [`event:tool/ptc-dispatch`](#persistence-type-eventtoolptc-dispatch) | +| `event:tool/ptc-dispatch-start` | event | `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` | [`event:tool/ptc-dispatch-start`](#persistence-type-eventtoolptc-dispatch-start) | +| `event:tool/result` | event | `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` | [`event:tool/result`](#persistence-type-eventtoolresult) | +| `event:turn/end` | event | `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` | [`event:turn/end`](#persistence-type-eventturnend) | +| `event:turn/start` | event | `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` | [`event:turn/start`](#persistence-type-eventturnstart) | +| `event:user/message` | event | `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` | [`event:user/message`](#persistence-type-eventusermessage) | +| `event:web/deepseek-search-llm-request` | event | `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` | [`event:web/deepseek-search-llm-request`](#persistence-type-eventwebdeepseek-search-llm-request) | + +
+完整解析类型 + +### 已解析的持久化类型 + +每个类型定义仅列出一次。引用保留共享和递归关系;定义旁的摘要涵盖其完整可达结构。源码名称和位置标识声明来源,但不参与摘要计算。 + + + +#### `0` + +SHA-256: `93d38436347f67c9022aacbc4472e283d722bcab8eb73fc376aaf7b6a6b9fb35` + +`0` + + + +#### `1` + +SHA-256: `f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d` + +`1` + + + +#### `2` + +SHA-256: `a0f906856fc06f1c6f2083eb970e5a657a82b1a84c06c095445e5d6d161cda80` + +`2` + + + +#### `3` + +SHA-256: `137ac60e26bcb192210d9a32a704b73b0924ed34019323defa1b787be95bd45e` + +`3` + + + +#### `"aborted"` + +SHA-256: `1e0b0b66b6f0c53fc72e52289d06b4708d776f1ca9df4c86a22bff621d403cf0` + +`"aborted"` + + + +#### `"active"` + +SHA-256: `c8e6f48878cc2a2f0dc59682280d81f407943fb503f32c64bf9ff3d9393c3eff` + +`"active"` + + + +#### `"after"` + +SHA-256: `5b232a9b9bfcc0fc6794dab7865bcf203a65785c5de5aa647a51228bff628413` + +`"after"` + + + +#### `"agent-instructions"` + +SHA-256: `fbd2c74b346a1595b376139c587fadd23e4a21acc9c0abce342975b6cfc60986` + +`"agent-instructions"` + + + +#### `"agent-message"` + +SHA-256: `82470020b5bfcb1a843e2aa05602af7d37df99e82d01f015c7c589ba054fd89d` + +`"agent-message"` + + + +#### `"agent-preset/selected"` + +SHA-256: `557e148d30b79ee48645850832b30c717d7c3b64641deb5d6133b8b4e91ee0b8` + +`"agent-preset/selected"` + + + +#### `"agent/inbox/spliced"` + +SHA-256: `829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809` + +`"agent/inbox/spliced"` + + + +#### `"allowed-once"` + +SHA-256: `811229eedcec57979dbadca7dbea832a59f8580cff30cb217fca5e2da16314bd` + +`"allowed-once"` + + + +#### `"always"` + +SHA-256: `142c37d302aa22a0a57915b5255939d3ca91c1811ca13fddcf84cf76ea00758a` + +`"always"` + + + +#### `"append"` + +SHA-256: `e438a9d4fb883b3e4a8d9fc8913aa1550ed50eb384bfbf943100a5605b537498` + +`"append"` + + + +#### `"approval/asked"` + +SHA-256: `cd186c309e2bef305705e1d324139240f5e681f4f6a957d6a25b0225f65560df` + +`"approval/asked"` + + + +#### `"approval/decided"` + +SHA-256: `378f90f9f6022a0991928a1eaf7991094ea1920fe89a9248358a1da106e1a970` + +`"approval/decided"` + + + +#### `"approval/policy"` + +SHA-256: `36d6a9a871d949ea4f3edd919d81d66aa69218bebef38899d2a1282c39420a1f` + +`"approval/policy"` + + + +#### `"ask"` + +SHA-256: `9e07693fd7cd9babe0688c22c986e4d519ae1c0e40eeea13b2dc583bed2abc86` + +`"ask"` + + + +#### `"assistant"` + +SHA-256: `95c0e88fcf0bafb2087f912ad9e2369de6ae6530cc0c4c2772c96205b57f7f60` + +`"assistant"` + + + +#### `"assistant/attempt"` + +SHA-256: `e95f957154b2b1b58692af53d4131180b6dd19e2264869f876dbaa959991494e` + +`"assistant/attempt"` + + + +#### `"assistant/message"` + +SHA-256: `6ab45ac76839722df912f3ba50f1c6b41f2d614bde11f1aabfae04117ccdc80d` + +`"assistant/message"` + + + +#### `"at"` + +SHA-256: `17aae616ef020b8b9f011ec398ec935450fb06d3e2a0722c456f63aeaf5ff728` + +`"at"` + + + +#### `"block"` + +SHA-256: `1e346446e183ee76f48d7994c97ecb302bddc682abb60b8a10ea0bb26223a69c` + +`"block"` + + + +#### `"block-end"` + +SHA-256: `eefbea819caeeea91ccb02dfafc16c68dd7f961cf9c1b2be25a2084509cf5c5a` + +`"block-end"` + + + +#### `"block-start"` + +SHA-256: `cbca49bde16b656d5b8fbe4a8a507769f7b594c6287782b809c03814941bc5e3` + +`"block-start"` + + + +#### `"blocked"` + +SHA-256: `254dce209e735f9cb6f6b7aec0354712b1611759ec02af4d35a96f2081e666f6` + +`"blocked"` + + + +#### `boolean` + +SHA-256: `aa93010d0e521ad7c42273f58d5c9b8bf1dfc94edf1b805a3971b364a35c1877` + +`boolean` + + + +#### `"canceled"` + +SHA-256: `d4e4d575abeb4b72d616dc65c17ac0eaa943cc135609395044c38d5afcb10e31` + +`"canceled"` + + + +#### `"cancelled"` + +SHA-256: `2142e391b9ccb60d487afcf373ce74db98d952f69e8289eddb352a7e16e996c5` + +`"cancelled"` + + + +#### `"catalog"` + +SHA-256: `aec150797b655c5f15ebb7a501454b0c208fbaccec9ace49d7de2171fc02f47d` + +`"catalog"` + + + +#### `"change"` + +SHA-256: `f789af5ab844827eb5a4f357c0afae1eeed108c6c22d8ca1a56e586b349a7c85` + +`"change"` + + + +#### `"chunk"` + +SHA-256: `14230f9b8b5797bb7e8c621fa636531cfbde2ffba1ef5f1fd058216ff21952a0` + +`"chunk"` + + + +#### `"claude-code"` + +SHA-256: `aff60ef947c18b012644852bdd0d5bfe72065e061dd563787c76c646b4a10f6b` + +`"claude-code"` + + + +#### `"clear"` + +SHA-256: `e7e154d47d5fbc5366330fb4dade1f108c6dfe4335044d21ded14b7bf1dce084` + +`"clear"` + + + +#### `"codex"` + +SHA-256: `15495614ccfa9cbdeefb0ec2abd76406435f4c6ff3dae42acae8e09ef42025c9` + +`"codex"` + + + +#### `"command/done"` + +SHA-256: `8cdd3fdd295cee53035de16a1b23411716f75e9f994fe9510cac5d7fef605c76` + +`"command/done"` + + + +#### `"command/run"` + +SHA-256: `f1996af2602e6f62b5ab179ca5c4af00d8753938b74cc6ef102de09e99e74a7e` + +`"command/run"` + + + +#### `"compaction/end"` + +SHA-256: `1986c2664009c99155e44795676c887fa67f7c55cd2d5e6b648ff763e0ab033a` + +`"compaction/end"` + + + +#### `"compaction/prune"` + +SHA-256: `10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe` + +`"compaction/prune"` + + + +#### `"compaction/start"` + +SHA-256: `e2d0367e5716bc188435e51718ebff8ce873190625fa93b1c5331102d98758fa` + +`"compaction/start"` + + + +#### `"compaction/summary"` + +SHA-256: `ef4f00923b9edbae15c7ef05320280bf61147ca17146cf59690359bfd5e5da45` + +`"compaction/summary"` + + + +#### `"complete"` + +SHA-256: `d9196086e41e4dd5c2ce87f5c25529c8112a1731d258cf0728747d41a9ee3241` + +`"complete"` + + + +#### `"completed"` + +SHA-256: `1ebc6f9ff3aa9e3a38f8695f49bacdab1f8b7a3832741853ca46f40af56ccd01` + +`"completed"` + + + +#### `"continuable"` + +SHA-256: `e5d3828df1ec3e2a66879de0659e0f4866d9cfffc00825ee731a66f8a0c03d98` + +`"continuable"` + + + +#### `"create"` + +SHA-256: `7624ca28c61ca0eaa4f015140f3cea6e0c16cce2f2960fab5f531203d253903e` + +`"create"` + + + +#### `"danger-full-access"` + +SHA-256: `18fce9540bb20897a66275499faee6b8296c97e9901fa1ff45a191772448ad1a` + +`"danger-full-access"` + + + +#### `"delegation"` + +SHA-256: `76632533f67879dcb346fcae640540dbc89b2472b0bce88c59f7e48fc5c0e668` + +`"delegation"` + + + +#### `"delete"` + +SHA-256: `d0fbb0ca1bbba059830826f33f801da1aced35a2504376d61e020bdfec8d50c0` + +`"delete"` + + + +#### `"deleted"` + +SHA-256: `e7e8f1318170b8284f16ab45a557afd4675c96071c0f2a456636481dab20b427` + +`"deleted"` + + + +#### `"deliverables/presented"` + +SHA-256: `1a2718b00937b236a0d0910ef5dab2f9f8b65e4bde410cc21f15fbbf29f584d3` + +`"deliverables/presented"` + + + +#### `"dispatch"` + +SHA-256: `26c879bdd130e8b8683a6ce588414fad2244783d6573ca399fa0de184a2b0bb1` + +`"dispatch"` + + + +#### `"disposed"` + +SHA-256: `b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751` + +`"disposed"` + + + +#### `"edit"` + +SHA-256: `ad22a5ca5bbaab2e1440779cd3648e85ddfc6f73b5207394eda699555cf31430` + +`"edit"` + + + +#### `"error"` + +SHA-256: `a2be0f0cb59f0d4a06557d45847d1938aced238baa77a6da416e590b8b958553` + +`"error"` + + + +#### `event:agent-preset/selected` + +SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:agent-preset/selected.data`](#persistence-type-eventagent-presetselecteddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"agent-preset/selected"` | + + + +#### `event:agent-preset/selected.data` + +SHA-256: `6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406` + +来源:`packages/preset/agent-presets/src/session.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentPreset` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced` + +SHA-256: `646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:agent/inbox/spliced.data`](#persistence-type-eventagentinboxspliceddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"agent/inbox/spliced"` | + + + +#### `event:agent/inbox/spliced.data` + +SHA-256: `a6a195c1b4a906d953d24ab5864c9f1881d545460e080a51144adfc9cb058cfe` + +来源:`packages/core/agent/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `inserted` | 必需 | [`event:agent/inbox/spliced.data.inserted`](#persistence-type-eventagentinboxspliceddatainserted) | +| `outcome` | 可选 | `"canceled"` | +| `removedCount` | 可选 | `number` | +| `start` | 必需 | `number` | +| `target` | 必需 | [`packages/core/agent/src/types.ts#InboxTarget`](#persistence-type-packagescoreagentsrctypestsinboxtarget) | + + + +#### `event:agent/inbox/spliced.data.inserted` + +SHA-256: `300341f890f7b9506a1749fff4fa5239d16ea1c63ff6b15851acb03c20f3b48d` + +[`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage) 的数组。 + + + +#### `event:agent/inbox/spliced.data.inserted[0].content` + +SHA-256: `bb72d86bc9ef0b3908bfa57ef98ccccae24d67d945c9f6869ca3cb8577889e75` + +[`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock) 的数组。 + + + +#### `event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions` + +SHA-256: `0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef` + +来源:`packages/attachment/attachment/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `height` | 必需 | `number` | +| `width` | 必需 | `number` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[0]` + +SHA-256: `ada310bf0bdb8fed51f3b56ea63f6ea6b18bbd587f04fccb63a14ab0b2a24e05` + +来源:`packages/core/session/src/types.ts` · `packages/interaction/commands/src/types.ts` · `packages/llm/llm/src/message.ts` · `packages/session/session-title/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"user"` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[1]` + +SHA-256: `0ddab4577db37a3e0d9e3a91761735c8ef6f5629d526ab8ecaeeea19c097c8f8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[10]` + +SHA-256: `6a4f72e2e179e17b922f2a9392c0e1c8f8c707f32494372454850a3eb184a6e7` + +来源:`packages/api/session-controller/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `clientTimeZone` | 可选 | `string` | +| `kind` | 必需 | `"user"` | +| `rpcId` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[15].references` + +SHA-256: `df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18` + +[`event:agent/inbox/spliced.data.inserted[0].source[15].references[0]`](#persistence-type-eventagentinboxspliceddatainserted0source15references0) 的数组。 + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[15].references[0]` + +SHA-256: `4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4` + +来源:`packages/context/session-reference/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `capturedFormatVersion` | 可选 | `number` | +| `capturedThroughSeq` | 必需 | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | +| `compacted` | 必需 | `boolean` | +| `inputIndex` | 必需 | `number` | +| `label` | 必需 | `string` | +| `omittedBytes` | 必需 | `number` | +| `omittedMessages` | 必需 | `number` | +| `originalMessages` | 必需 | `number` | +| `retainedMessages` | 必需 | `number` | +| `sessionId` | 必需 | `string` | +| `truncated` | 必需 | `boolean` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[16].changes` + +SHA-256: `2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee` + +[`packages/context/agent-instructions/src/render.ts#AgentInstructionChange`](#persistence-type-packagescontextagent-instructionssrcrendertsagentinstructionchange) 的数组。 + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action` + +SHA-256: `904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd` + +以下类型之一: + +- `"remove"` +- `"replace"` +- `"set"` + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[17].entries` + +SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` + +[`event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]`](#persistence-type-eventagentinboxspliceddatainserted0source17entries0) 的数组。 + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]` + +SHA-256: `83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693` + +来源:`packages/skill/tool-skill/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `description` | 必需 | `string` | +| `name` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[19]` + +SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` + +来源:`packages/webhook/webhook/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `deliveryId` | 必需 | `string` | +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"webhook"` | +| `provider` | 必需 | `string` | +| `ruleId` | 必需 | `string` | +| `source` | 必需 | `string` | +| `summary` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[2]` + +SHA-256: `dda6e111a8ccfc12f6e742e977a1a4e3549e8c03732a5ff6c8d7c3d4bcb7a412` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[3]` + +SHA-256: `2f90a7b3646fea3e677bd7b4000aa96f3b8964f107b614e204e11ad4051c24fc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[4]` + +SHA-256: `e8d26e6993445743e6c4342c31b284c7d8f5574369abdd6021183af1a6b3538f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"snapshot"` | +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | +| `sections` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[4].sections`](#persistence-type-eventagentinboxspliceddatainserted0source4sections) | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[4].sections` + +SHA-256: `c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262` + +[`packages/llm/llm/src/message.ts#ContextSnapshotSection`](#persistence-type-packagesllmllmsrcmessagetscontextsnapshotsection) 的数组。 + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[5]` + +SHA-256: `b4d298d90c798fa4d1f5b030ce3ce8031c4c41beafdb05323bec8b2a06903b43` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | +| `summary` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[6]` + +SHA-256: `2ce7ef3b3daebf95815c7ae454a751d3e67ca7a22e2e0734fe2942df393bb66c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | + + + +#### `event:agent/inbox/spliced.data.inserted[0].source[7]` + +SHA-256: `85e1bd563d6c80c1f377f99f91103fec4e315148a7330f3b3dae7c2d04e33b01` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"plugin"` | +| `plugin` | 必需 | `string` | + + + +#### `event:approval/asked` + +SHA-256: `3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:approval/asked.data`](#persistence-type-eventapprovalaskeddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"approval/asked"` | + + + +#### `event:approval/asked.data` + +SHA-256: `45f2a07ea94573123b6ae14db787a40062dec3834f36d8be92c523d40ba28448` + +来源:`packages/interaction/user-approval/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `callId` | 可选 | `string` | +| `id` | 必需 | `string` | +| `reason` | 可选 | `string` | +| `toolName` | 必需 | `string` | + + + +#### `event:approval/decided` + +SHA-256: `bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:approval/decided.data`](#persistence-type-eventapprovaldecideddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"approval/decided"` | + + + +#### `event:approval/decided.data` + +SHA-256: `93cbbc5a7fd0b1aa1ff1b9a6bb5ec52b073f48e5a5200365c45c0cd54059e1b9` + +来源:`packages/interaction/user-approval/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `outcome` | 必需 | [`packages/interaction/user-approval/src/types.ts#ApprovalOutcome`](#persistence-type-packagesinteractionuser-approvalsrctypestsapprovaloutcome) | + + + +#### `event:approval/policy` + +SHA-256: `26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:approval/policy.data`](#persistence-type-eventapprovalpolicydata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"approval/policy"` | + + + +#### `event:approval/policy.data` + +SHA-256: `11f70b595aa76897fc4e25a352bfa718c659f44b799e5aa14e84e5a38fe72912` + +来源:`packages/interaction/user-approval/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `policy` | 必需 | [`packages/interaction/user-approval/src/index.ts#ApprovalPolicy`](#persistence-type-packagesinteractionuser-approvalsrcindextsapprovalpolicy) | +| `source` | 可选 | `"delegation"` | + + + +#### `event:assistant/attempt` + +SHA-256: `c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:assistant/attempt.data`](#persistence-type-eventassistantattemptdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"assistant/attempt"` | + + + +#### `event:assistant/attempt.data` + +SHA-256: `0c6412d3ba5e41adfaa6929c7d4093f2d52d8598c03f35844fc0d55e3070a3b1` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `step` | 必需 | `number` | +| `stream` | 必需 | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | +| `turn` | 必需 | `number` | + + + +#### `event:assistant/attempt.data.stream` + +SHA-256: `26f3bb7529cfce1e3a0f1ededa365d8b426758ca0feeb0beabeee805f8bb8346` + +[`packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord`](#persistence-type-packagesllmllmsrcassistant-streamtsassistantstreamrecord) 的数组。 + + + +#### `event:assistant/attempt.data.stream[0][0]` + +SHA-256: `e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33` + +来源:`packages/llm/llm/src/assistant-stream.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `dt` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `index` | 必需 | `number` | +| `texts` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `time0` | 必需 | `number` | +| `type` | 必需 | `"text-chunks"` | + + + +#### `event:assistant/attempt.data.stream[0][0].texts` + +SHA-256: `93c33d9687613293f8c95d46c4d922fe9ceae83b84c384beff5c3315abe005f2` + +`string` 的数组。 + + + +#### `event:assistant/attempt.data.stream[0][1]` + +SHA-256: `71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd` + +来源:`packages/llm/llm/src/assistant-stream.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `dt` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `index` | 必需 | `number` | +| `texts` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `time0` | 必需 | `number` | +| `type` | 必需 | `"reasoning-chunks"` | + + + +#### `event:assistant/attempt.data.stream[0][2]` + +SHA-256: `3860b4757d512a2869be833acb0faf834335b1b056bf3f83df5474dce95f8fa6` + +来源:`packages/llm/llm/src/assistant-stream.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `args` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `dt` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `id` | 必需 | `string` | +| `index` | 必需 | `number` | +| `name` | 可选 | `string` | +| `time0` | 必需 | `number` | +| `type` | 必需 | `"tool-call-chunks"` | + + + +#### `event:assistant/attempt.data.stream[0][3]` + +SHA-256: `c93b6f51b399607349b4bcc66b58e848a44250ffc1e2537207bd092dfff94192` + +来源:`packages/llm/llm/src/assistant-stream.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `chunk` | 必需 | [`packages/llm/llm/src/types.ts#StreamChunk`](#persistence-type-packagesllmllmsrctypestsstreamchunk) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"chunk"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[0]` + +SHA-256: `647cb2e3aeb58e27d1d4d60011f208bb66dce257e8654193c533b47c4c22c253` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blockType` | 必需 | [`packages/llm/llm/src/types.ts#ContentBlockType`](#persistence-type-packagesllmllmsrctypestscontentblocktype) | +| `index` | 必需 | `number` | +| `type` | 必需 | `"block-start"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[1]` + +SHA-256: `95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `index` | 必需 | `number` | +| `text` | 必需 | `string` | +| `type` | 必需 | `"text-delta"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[2]` + +SHA-256: `2abb711460e6238d851c30f3e4bdd87a2aa1887ee70575b3d3b7b25610673095` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `index` | 必需 | `number` | +| `text` | 必需 | `string` | +| `type` | 必需 | `"reasoning-delta"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[3]` + +SHA-256: `88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `argumentsDelta` | 必需 | `string` | +| `id` | 必需 | `string` | +| `index` | 必需 | `number` | +| `name` | 可选 | `string` | +| `type` | 必需 | `"tool-call-delta"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[4]` + +SHA-256: `90c811b8c2668898515e69a24e82caffeb08517f9c7aa193867ff0380f3b535d` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `block` | 必需 | [`packages/llm/llm/src/types.ts#ContentBlock`](#persistence-type-packagesllmllmsrctypestscontentblock) | +| `index` | 必需 | `number` | +| `type` | 必需 | `"block-end"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[5]` + +SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `type` | 必需 | `"usage"` | +| `usage` | 必需 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6]` + +SHA-256: `a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `reason` | 必需 | [`packages/llm/llm/src/types.ts#FinishReason`](#persistence-type-packagesllmllmsrctypestsfinishreason) | +| `replayState` | 可选 | [`packages/llm/llm/src/types.ts#ReplayEnvelope`](#persistence-type-packagesllmllmsrctypestsreplayenvelope) | +| `type` | 必需 | `"finish"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]` + +SHA-256: `8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `kind` | 必需 | `"aborted"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]` + +SHA-256: `693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `kind` | 必需 | `"error"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]` + +SHA-256: `ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7` + +来源:`packages/core/session/src/types.ts` · `packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"max-tokens"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]` + +SHA-256: `1d76406cbb2ddadb0dbbb51e9d8bc6cf678fed455cf8eb512f36f7c86d37a62f` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"stop"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]` + +SHA-256: `287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"tool-calls"` | + + + +#### `event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks` + +SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7` + +`unknown`(不透明) 的数组。 + + + +#### `event:assistant/message` + +SHA-256: `1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:assistant/message.data`](#persistence-type-eventassistantmessagedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"assistant/message"` | + + + +#### `event:assistant/message.data` + +SHA-256: `77b8491f946edfc8cc77ebae3ba49183759da31ba2dfa83d4c9e9e618c4b91d2` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `interrupted` | 可选 | `true` | +| `message` | 必需 | [`packages/llm/llm/src/message.ts#AssistantMessage`](#persistence-type-packagesllmllmsrcmessagetsassistantmessage) | +| `step` | 必需 | `number` | +| `stream` | 必需 | [`event:assistant/attempt.data.stream`](#persistence-type-eventassistantattemptdatastream) | +| `turn` | 必需 | `number` | +| `usage` | 可选 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:command/done` + +SHA-256: `15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:command/done.data`](#persistence-type-eventcommanddonedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"command/done"` | + + + +#### `event:command/done.data` + +SHA-256: `5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51` + +来源:`packages/interaction/commands/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `commandId` | 必需 | `string` | +| `kind` | 必需 | [`event:command/done.data.kind`](#persistence-type-eventcommanddonedatakind) | +| `sourceEventSeq` | 可选 | `number` | +| `text` | 可选 | `string` | + + + +#### `event:command/done.data.kind` + +SHA-256: `1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92` + +以下类型之一: + +- `"error"` +- `"success"` + + + +#### `event:command/run` + +SHA-256: `37184378c6439257d105c4e2022d80fc9c3a3f7c7f6ac661b00bc9f18d871006` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:command/run.data`](#persistence-type-eventcommandrundata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"command/run"` | + + + +#### `event:command/run.data` + +SHA-256: `a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86` + +来源:`packages/interaction/commands/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `args` | 可选 | `string` | +| `commandId` | 必需 | `string` | +| `name` | 必需 | `string` | +| `source` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) | + + + +#### `event:compaction/end` + +SHA-256: `b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:compaction/end.data`](#persistence-type-eventcompactionenddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/end"` | + + + +#### `event:compaction/end.data` + +SHA-256: `ca59530d1a4f3e191b4032bc4a20eded0d827db8b5a7efb27b3af9e9b456c6f2` + +来源:`packages/compaction/compaction/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `error` | 可选 | `string` | +| `sourceCommandId` | 可选 | `string` | +| `turn` | 必需 | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | + + + +#### `event:compaction/end.data.turn` + +SHA-256: `3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f` + +来源:`packages/core/session/src/types.ts` + +以下类型之一: + +- `null` +- `number` + + + +#### `event:compaction/prune` + +SHA-256: `7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:compaction/prune.data`](#persistence-type-eventcompactionprunedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/prune"` | + + + +#### `event:compaction/prune.data` + +SHA-256: `5dd766ccd1702a1142ad8b4bd44f2242f8e8a6752669ad3de0a5d224329b1438` + +来源:`packages/compaction/compaction/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `shadowedRange` | 必需 | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | +| `shadowedSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `shadowedTokenCount` | 必需 | `number` | + + + +#### `event:compaction/prune.data.shadowedRange` + +SHA-256: `9e41386b3a0c9572b0d63078492ebb3997da7d3a830d44e0259418bd02f4bcb2` + +来源:`packages/compaction/compaction/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `end` | 必需 | `number` | +| `start` | 必需 | `number` | + + + +#### `event:compaction/start` + +SHA-256: `db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:compaction/start.data`](#persistence-type-eventcompactionstartdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/start"` | + + + +#### `event:compaction/start.data` + +SHA-256: `3e4e7683b0192c9f0e6a75c59076108f017892cdb302a98032c2632fd79c356f` + +来源:`packages/compaction/compaction/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `sourceCommandId` | 可选 | `string` | +| `turn` | 必需 | [`event:compaction/end.data.turn`](#persistence-type-eventcompactionenddataturn) | + + + +#### `event:compaction/summary` + +SHA-256: `f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:compaction/summary.data`](#persistence-type-eventcompactionsummarydata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"compaction/summary"` | + + + +#### `event:compaction/summary.data` + +SHA-256: `feb329074f0206ecc06d8a1aa0a0b3e2f47fd27524ba020fbc849ba63e938896` + +以下类型之一: + +- [`event:compaction/summary.data[0]`](#persistence-type-eventcompactionsummarydata0) +- [`event:compaction/summary.data[1]`](#persistence-type-eventcompactionsummarydata1) + + + +#### `event:compaction/summary.data[0]` + +SHA-256: `9ff2ad8dddb836f75e8f6197fff2371323dfc396c3c6fb667e6e0b42fda79a5c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `llmStreamCall` | 必需 | `true` | +| `maxTokens` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `rawOutput` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `shadowedRange` | 必需 | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | +| `shadowedSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `shadowedTokenCount` | 必需 | `number` | +| `sourceCommandId` | 可选 | `string` | +| `summary` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `usage` | 可选 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:compaction/summary.data[1]` + +SHA-256: `3aa261c8516b5c955ed12080e6257a56cbe513f6c9f0ac9274c12e96c196ebca` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `compactionId` | 必需 | `string` | +| `maxTokens` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `rawOutput` | 可选 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `shadowedRange` | 必需 | [`event:compaction/prune.data.shadowedRange`](#persistence-type-eventcompactionprunedatashadowedrange) | +| `shadowedSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `shadowedTokenCount` | 必需 | `number` | +| `sourceCommandId` | 可选 | `string` | +| `summary` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `usage` | 可选 | [`packages/llm/llm/src/types.ts#TokenUsage`](#persistence-type-packagesllmllmsrctypeststokenusage) | + + + +#### `event:deliverables/presented` + +SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:deliverables/presented.data`](#persistence-type-eventdeliverablespresenteddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"deliverables/presented"` | + + + +#### `event:deliverables/presented.data` + +SHA-256: `1528539c63db8b23506f0209a99ce77d8ad138adfbfcee3d4769b7382d93756c` + +来源:`packages/fs/tool-present/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `callId` | 必需 | `string` | +| `files` | 必需 | [`event:deliverables/presented.data.files`](#persistence-type-eventdeliverablespresenteddatafiles) | +| `turn` | 必需 | `number` | + + + +#### `event:deliverables/presented.data.files` + +SHA-256: `1d9cb3caa96100b18b1911fa3ff8c751ef6992971a03c5f4d9aefc1a0004a345` + +[`packages/fs/tool-present/src/types.ts#PresentedFile`](#persistence-type-packagesfstool-presentsrctypestspresentedfile) 的数组。 + + + +#### `event:feedback/message-delete` + +SHA-256: `3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackdelete) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"feedback/message-delete"` | + + + +#### `event:feedback/message-put` + +SHA-256: `b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackput) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"feedback/message-put"` | + + + +#### `event:feedback/message-put.data.item.category` + +SHA-256: `3305a4bb6b6c29b482ba91d59c60b47e8f98282d3dacc8c29e4a4c2712209bdd` + +以下类型之一: + +- `"instruction-following"` +- `"other"` +- `"product-interaction"` +- `"resource-cost"` +- `"security-privacy-permission"` +- `"service-stability"` +- `"task-result"` + + + +#### `event:feedback/record` + +SHA-256: `b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/feedback/command-feedback/src/types.ts#FeedbackRecord`](#persistence-type-packagesfeedbackcommand-feedbacksrctypestsfeedbackrecord) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"feedback/record"` | + + + +#### `event:goal/change` + +SHA-256: `763c8a20af487263a0080548274f7437ef4a86e0ba8769127d1ced10a72c664d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/goal/goal/src/domain.ts#GoalChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalchangemeta) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"goal/change"` | + + + +#### `event:goal/change.data[0].operation` + +SHA-256: `62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379` + +以下类型之一: + +- `"block"` +- `"complete"` +- `"create"` +- `"edit"` +- `"pause"` +- `"resume"` + + + +#### `event:hook/invoked` + +SHA-256: `8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:hook/invoked.data`](#persistence-type-eventhookinvokeddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"hook/invoked"` | + + + +#### `event:hook/invoked.data` + +SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` + +来源:`packages/hooks/hook-protocol/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `dialect` | 必需 | [`packages/hooks/hook-protocol/src/types.ts#HookDialect`](#persistence-type-packageshookshook-protocolsrctypestshookdialect) | +| `handlerId` | 必需 | `string` | +| `matcher` | 可选 | `string` | +| `point` | 必需 | `string` | +| `turn` | 必需 | `number` | + + + +#### `event:hook/result` + +SHA-256: `e75916628f3f10c2d50658bd143052a46285fbf1a9a700ba54947614603d26b4` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:hook/result.data`](#persistence-type-eventhookresultdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"hook/result"` | + + + +#### `event:hook/result.data` + +SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` + +来源:`packages/hooks/hook-protocol/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `decision` | 必需 | `string` | +| `durationMs` | 必需 | `number` | +| `exitCode` | 可选 | `number` | +| `handlerId` | 必需 | `string` | +| `point` | 必需 | `string` | +| `stderrSummary` | 可选 | `string` | +| `turn` | 必需 | `number` | + + + +#### `event:image/offload` + +SHA-256: `b222069eea2d768065161c1147b1f2c78c1b54328c84b3586ae5c8f91b8ed35e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:image/offload.data`](#persistence-type-eventimageoffloaddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"image/offload"` | + + + +#### `event:image/offload.data` + +SHA-256: `477614bca595a9e7adb5a1870be446b9a8684f3ba8950259d6289f2d3b74f028` + +来源:`packages/compaction/compaction-image-offload/src/projection.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `targets` | 必需 | [`event:image/offload.data.targets`](#persistence-type-eventimageoffloaddatatargets) | + + + +#### `event:image/offload.data.targets` + +SHA-256: `9e2c06d8653585b33d72d5c1a80da79c8a24a88c284409bca15cc0f0ead5ebfb` + +[`packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget`](#persistence-type-packagescompactioncompaction-image-offloadsrcprojectiontsimageoffloadtarget) 的数组。 + + + +#### `event:llm/retry` + +SHA-256: `525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/llm/llm-retry/src/types.ts#LlmRetryEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretryeventdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"llm/retry"` | + + + +#### `event:llm/retry-started` + +SHA-256: `48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData`](#persistence-type-packagesllmllm-retrysrctypestsllmretrystartedeventdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"llm/retry-started"` | + + + +#### `event:llm/retry.data[0]` + +SHA-256: `cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced` + +来源:`packages/llm/llm-retry/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `delayMs` | 必需 | `number` | +| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `maxRetries` | 必需 | `number` | +| `mode` | 必需 | `"normal"` | +| `policyKey` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `retry` | 必需 | `number` | +| `retryId` | 必需 | `string` | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `event:llm/retry.data[1]` + +SHA-256: `374fdd68aee5ff844e378c0cbdd961d247a0f22e4ade0bb03d800cd2a46a2b8b` + +来源:`packages/llm/llm-retry/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `delayMs` | 必需 | `number` | +| `failure` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `mode` | 必需 | `"always"` | +| `policyKey` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `retry` | 必需 | `number` | +| `retryId` | 必需 | `string` | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `event:model/selection` + +SHA-256: `35203ba7ad5ef6f97d556b85df20ae98f04f09c65748cecdf8eefdb8b6405ffc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/api/session-controller/src/types.ts#ModelSelection`](#persistence-type-packagesapisession-controllersrctypestsmodelselection) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"model/selection"` | + + + +#### `event:permission/preset` + +SHA-256: `5c45bf4c544a7211dcd8ba6ba7e5f1bc39b49e7a9df9d5cbdc8e87c22771b37b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:permission/preset.data`](#persistence-type-eventpermissionpresetdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"permission/preset"` | + + + +#### `event:permission/preset.data` + +SHA-256: `8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad` + +来源:`packages/interaction/permission-presets/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `preset` | 必需 | `string` | + + + +#### `event:plan/mode` + +SHA-256: `a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:plan/mode.data`](#persistence-type-eventplanmodedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"plan/mode"` | + + + +#### `event:plan/mode.data` + +SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5` + +来源:`packages/plan/plan-mode/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `active` | 必需 | `boolean` | + + + +#### `event:request/context` + +SHA-256: `37cbc9cf06d494cfe5c67f078af1605eacb8e4c2c853e9e26455b73de0ee7ccf` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/core/session/src/types.ts#RequestContext`](#persistence-type-packagescoresessionsrctypestsrequestcontext) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"request/context"` | + + + +#### `event:request/header` + +SHA-256: `8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:request/header.data`](#persistence-type-eventrequestheaderdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"request/header"` | + + + +#### `event:request/header.data` + +SHA-256: `2f0aefb72ab453c4bf21a6687f436775d359dc6f8f10410fd4c0615b20bd9d76` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `header` | 必需 | [`packages/core/session/src/types.ts#EpochHeader`](#persistence-type-packagescoresessionsrctypestsepochheader) | +| `reason` | 必需 | [`packages/core/session/src/types.ts#RequestHeaderReason`](#persistence-type-packagescoresessionsrctypestsrequestheaderreason) | +| `startsSeries` | 可选 | `true` | + + + +#### `event:request/header.data.header.tools` + +SHA-256: `6d63f25a28b70801937a46b1058be5f52d4efbaf3516141470463ae469b59c23` + +[`packages/llm/llm/src/types.ts#ToolSchema`](#persistence-type-packagesllmllmsrctypeststoolschema) 的数组。 + + + +#### `event:request/header.data.header.tools[0].parameters` + +SHA-256: `0aa62ab51b36c0e64b134bd03ba8725d758744180a1a447da49beaad194f219f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| [`string`] | 索引签名 | `unknown`(不透明) | + + + +#### `event:sandbox/mode` + +SHA-256: `516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:sandbox/mode.data`](#persistence-type-eventsandboxmodedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"sandbox/mode"` | + + + +#### `event:sandbox/mode.data` + +SHA-256: `9890113e97dd3541787bfe6704f2b223d3a890b5325ca0acae2b0398909b413e` + +来源:`packages/sandbox/sandbox-policy/src/session-mode.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `mode` | 必需 | [`packages/sandbox/sandbox/src/index.ts#SandboxMode`](#persistence-type-packagessandboxsandboxsrcindextssandboxmode) | +| `source` | 可选 | `"delegation"` | + + + +#### `event:schedule/change` + +SHA-256: `2a7f86849ae54b3398ee49661a757c4fcb59a6192b7036ee2ff514617e13fb42` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/schedule/schedule/src/types.ts#ScheduleChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulechange) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"schedule/change"` | + + + +#### `event:session-log-deepseek/delivery-accepted` + +SHA-256: `d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:session-log-deepseek/delivery-accepted.data`](#persistence-type-eventsession-log-deepseekdelivery-accepteddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session-log-deepseek/delivery-accepted"` | + + + +#### `event:session-log-deepseek/delivery-accepted.data` + +SHA-256: `8bb8c3751a6ce64b61aba1ec7ae798c00a5803c4d868a0430873216c6569ed52` + +来源:`packages/session/session-log-deepseek/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `sessionFormatVersion` | 可选 | `number` | +| `sessionId` | 必需 | `string` | +| `throughSeq` | 必需 | `number` | + + + +#### `event:session/end-seed` + +SHA-256: `5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:session/end-seed.data`](#persistence-type-eventsessionend-seeddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session/end-seed"` | + + + +#### `event:session/end-seed.data` + +SHA-256: `17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `inherited` | 可选 | `true` | + + + +#### `event:session/title` + +SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/session/session-title/src/types.ts#SessionTitleEventData`](#persistence-type-packagessessionsession-titlesrctypestssessiontitleeventdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session/title"` | + + + +#### `event:session/title-llm-request` + +SHA-256: `e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData`](#persistence-type-packagessessionsession-title-llmsrcindextssessiontitlellmrequesteventdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"session/title-llm-request"` | + + + +#### `event:session/title-llm-request.data.messages` + +SHA-256: `478738df7e7d2b103b09fb937817a9302c81076809f2b341169e00a9419c5665` + +[`packages/llm/llm/src/message.ts#Message`](#persistence-type-packagesllmllmsrcmessagetsmessage) 的数组。 + + + +#### `event:session/title-llm-request.data.messages[0].role` + +SHA-256: `acd36e1717d2b4ef9e98a8e6fac17ca1203f3f448e5bca51677f129a8f4999e2` + +以下类型之一: + +- `"assistant"` +- `"system"` +- `"user"` + + + +#### `event:session/title.data.source[0]` + +SHA-256: `1b5649238876e28811e80f10ec67a00c197ad3babd4ecc61a22b09064b88c597` + +来源:`packages/session/session-title/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"fallback"` | + + + +#### `event:session/title.data.source[1]` + +SHA-256: `b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812` + +来源:`packages/session/session-title/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"provider"` | +| `model` | 可选 | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | +| `provider` | 必需 | `string` | + + + +#### `event:step/end` + +SHA-256: `e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:step/end.data`](#persistence-type-eventstependdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"step/end"` | + + + +#### `event:step/end.data` + +SHA-256: `ef11a3b7fa2033ae4279545ff8a8a2ee4e301b9b73e5b91654c48e6d08283545` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `event:step/start` + +SHA-256: `4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:step/end.data`](#persistence-type-eventstependdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"step/start"` | + + + +#### `event:subagent/catalog` + +SHA-256: `ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent`](#persistence-type-packagessubagentsubagentsrccatalogtssubagentcatalogevent) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"subagent/catalog"` | + + + +#### `event:subagent/catalog.data[0]` + +SHA-256: `5d542ac7bdf13310c46e1a884dec9fb18ad8c6e153cff207e639cd7bf9d7e694` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `childCreatedAt` | 必需 | `number` | +| `childId` | 必需 | `string` | +| `label` | 可选 | `string` | +| `mode` | 必需 | `"one-shot"` | +| `version` | 必需 | `0` | + + + +#### `event:subagent/catalog.data[1]` + +SHA-256: `0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `childCreatedAt` | 必需 | `number` | +| `childId` | 必需 | `string` | +| `label` | 必需 | `string` | +| `mode` | 必需 | `"continuable"` | +| `version` | 必需 | `0` | + + + +#### `event:subagent/descriptor` + +SHA-256: `b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortssubagentdescriptordata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"subagent/descriptor"` | + + + +#### `event:subagent/model-selection-policy` + +SHA-256: `a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:subagent/model-selection-policy.data`](#persistence-type-eventsubagentmodel-selection-policydata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"subagent/model-selection-policy"` | + + + +#### `event:subagent/model-selection-policy.data` + +SHA-256: `0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f` + +来源:`packages/subagent/tool-subagent/src/model-selection-state.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `allowedModels` | 必需 | [`event:subagent/model-selection-policy.data.allowedModels`](#persistence-type-eventsubagentmodel-selection-policydataallowedmodels) | + + + +#### `event:subagent/model-selection-policy.data.allowedModels` + +SHA-256: `ba77b58995e36f14bb13886b0493d0a1a63d5db10b1a6cd9f6ac65a72cf832ec` + +[`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) 的数组。 + + + +#### `event:system/message` + +SHA-256: `69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:system/message.data`](#persistence-type-eventsystemmessagedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"system/message"` | + + + +#### `event:system/message.data` + +SHA-256: `2074f40221b76c75fd314246db558965dc3477dfb440bcc952b1eedc9778e366` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `message` | 必需 | [`packages/llm/llm/src/message.ts#SystemMessage`](#persistence-type-packagesllmllmsrcmessagetssystemmessage) | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `event:system/message.data.message.source` + +SHA-256: `23cf7e0cf3fec1283b60fa15713506169bc9c079a08e124d1cb9733baca80b40` + +以下类型之一: + +- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) +- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) +- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) +- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) +- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) +- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) +- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) + + + +#### `event:team/member` + +SHA-256: `4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:team/member.data`](#persistence-type-eventteammemberdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/member"` | + + + +#### `event:team/member.data` + +SHA-256: `b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `member` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammembersnapshot) | +| `teamId` | 必需 | `string` | +| `version` | 必需 | `2` | + + + +#### `event:team/member.data.member.context` + +SHA-256: `50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48` + +以下类型之一: + +- `"fork"` +- `"fresh"` + + + +#### `event:team/message/delivered` + +SHA-256: `48f9c19417a1abbedfa59f4667bba36b93ac2db407adf5e84cb3ba0de30942cb` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:team/message/delivered.data`](#persistence-type-eventteammessagedelivereddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/message/delivered"` | + + + +#### `event:team/message/delivered.data` + +SHA-256: `0bcfaf5566d271028429ac7b562cb59053c9d78b8ae14708c35fac835108d1b1` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `messageId` | 必需 | `string` | +| `targetId` | 必需 | `string` | +| `teamId` | 必需 | `string` | +| `version` | 必需 | `2` | + + + +#### `event:team/message/queued` + +SHA-256: `443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:team/message/queued.data`](#persistence-type-eventteammessagequeueddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/message/queued"` | + + + +#### `event:team/message/queued.data` + +SHA-256: `0c3f4d2248d9bc9700e2d7253fa71aa9935f5c39af6f11de5727f08cccaf8383` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `message` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesnapshot) | +| `teamId` | 必需 | `string` | +| `version` | 必需 | `2` | + + + +#### `event:team/task` + +SHA-256: `d595ec73b32b016a6055333c67a5d646032b22e672da1d4a09c5b1ae398a093a` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:team/task.data`](#persistence-type-eventteamtaskdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"team/task"` | + + + +#### `event:team/task.data` + +SHA-256: `a40d12070f6f4a124f32fb3cc86e7857554702e32f0eda3080a25c4b9ac9b18c` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `task` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtasksnapshot) | +| `teamId` | 必需 | `string` | +| `version` | 必需 | `2` | + + + +#### `event:todo/write` + +SHA-256: `b978cff734e62143eb56c9125423ec275405eda969802d42aaf73ecb987d3b26` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:todo/write.data`](#persistence-type-eventtodowritedata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"todo/write"` | + + + +#### `event:todo/write.data` + +SHA-256: `79ddc907312f97cf9553d4841e8b3fc937097bd8d97900a790efad3c05255e99` + +来源:`packages/todo/tool-todo/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `todos` | 必需 | [`event:todo/write.data.todos`](#persistence-type-eventtodowritedatatodos) | + + + +#### `event:todo/write.data.todos` + +SHA-256: `4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea` + +[`packages/todo/tool-todo/src/types.ts#TodoItem`](#persistence-type-packagestodotool-todosrctypeststodoitem) 的数组。 + + + +#### `event:todo/write.data.todos[0].status` + +SHA-256: `fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4` + +以下类型之一: + +- `"completed"` +- `"in_progress"` +- `"pending"` + + + +#### `event:tool-workflow/agent-end` + +SHA-256: `babf9ee4d1af62bf6c3a8103737f7a5e4e78ce179be835ce05a38803e15884b7` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentenddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/agent-end"` | + + + +#### `event:tool-workflow/agent-start` + +SHA-256: `5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowagentstartdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/agent-start"` | + + + +#### `event:tool-workflow/run-end` + +SHA-256: `42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunenddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/run-end"` | + + + +#### `event:tool-workflow/run-start` + +SHA-256: `c1f9e0405de6d18cabb9ee70782a027f9bbdc57e5abec9dcccdd56119e2e9058` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData`](#persistence-type-packagesworkflowtool-workflowsrctypeststoolworkflowrunstartdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool-workflow/run-start"` | + + + +#### `event:tool/call` + +SHA-256: `3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:tool/call.data`](#persistence-type-eventtoolcalldata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/call"` | + + + +#### `event:tool/call.data` + +SHA-256: `e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `string` | +| `callId` | 必需 | `string` | +| `name` | 必需 | `string` | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `event:tool/ptc-dispatch` + +SHA-256: `b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/core/tools/src/types.ts#PtcDispatchEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatcheventdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/ptc-dispatch"` | + + + +#### `event:tool/ptc-dispatch-start` + +SHA-256: `ec38b5949af8eacaf00df002f4acbe344f934f8a061e9cdc65a52a48e5f6dd93` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/core/tools/src/types.ts#PtcDispatchStartEventData`](#persistence-type-packagescoretoolssrctypestsptcdispatchstarteventdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/ptc-dispatch-start"` | + + + +#### `event:tool/ptc-dispatch.data.error` + +SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735` + +来源:`packages/core/session/src/types.ts` · `packages/core/tools/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `code` | 必需 | `string` | +| `name` | 必需 | `string` | +| `reason` | 可选 | `string` | + + + +#### `event:tool/result` + +SHA-256: `29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:tool/result.data`](#persistence-type-eventtoolresultdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"tool/result"` | + + + +#### `event:tool/result.data` + +SHA-256: `356aad27134a0e31af67c994ff8b9e4b91acfb6c4917b3bc1f7a62bbf82794d5` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `error` | 可选 | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | +| `message` | 必需 | [`packages/llm/llm/src/message.ts#ToolResultMessage`](#persistence-type-packagesllmllmsrcmessagetstoolresultmessage) | +| `meta` | 可选 | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `event:tool/result.data.message.content` + +SHA-256: `8d6a011f3ef7096a4a922ef420458419ff6b20e1eaeece5d331db7585d2f08d6` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) | + + + +#### `event:tool/result.data.meta` + +SHA-256: `c592ce75aab73fcab19c1d7845684c72cf402b78d2e1f2833a58ecf9f3598ed6` + +来源:`packages/util/values/src/index.ts` + +以下类型之一: + +- [`event:tool/result.data.meta[5]`](#persistence-type-eventtoolresultdatameta5) +- [`event:tool/result.data.meta[5][0][6]`](#persistence-type-eventtoolresultdatameta506) +- `string` +- `boolean` +- `null` +- `number` + + + +#### `event:tool/result.data.meta[5]` + +SHA-256: `72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227` + +[`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) 的数组。 + + + +#### `event:tool/result.data.meta[5][0][6]` + +SHA-256: `529e0ccd0e34079ab4ff21ed87f810cee0388246263bf22e8aba5986b56fae05` + +来源:`packages/util/values/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| [`string`] | 索引签名 | [`event:tool/result.data.meta`](#persistence-type-eventtoolresultdatameta) | + + + +#### `event:turn/end` + +SHA-256: `bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:turn/end.data`](#persistence-type-eventturnenddata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"turn/end"` | + + + +#### `event:turn/end.data` + +SHA-256: `d3e447062a2847dad847dad5168a9508d92c484363dfc76fd82605aa7bd46285` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `reason` | 必需 | [`packages/core/session/src/types.ts#TurnEndReason`](#persistence-type-packagescoresessionsrctypeststurnendreason) | +| `turn` | 必需 | `number` | + + + +#### `event:turn/end.data.reason[0]` + +SHA-256: `b6ef9c6210be8350cd465f485cf520031fffa6bf3809c61a1e713e834c5982d0` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"completed"` | + + + +#### `event:turn/end.data.reason[1]` + +SHA-256: `0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"aborted"` | +| `reason` | 必需 | [`packages/core/session/src/types.ts#TurnEndCancelCause`](#persistence-type-packagescoresessionsrctypeststurnendcancelcause) | + + + +#### `event:turn/end.data.reason[1].reason[1]` + +SHA-256: `6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"parent"` | + + + +#### `event:turn/end.data.reason[1].reason[2]` + +SHA-256: `6c5a37d42ebdb12db4410699259335f1e149e3a0260425684c00b153afc8990d` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"hook"` | +| `reason` | 必需 | `string` | + + + +#### `event:turn/end.data.reason[1].reason[3]` + +SHA-256: `4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"disposed"` | + + + +#### `event:turn/end.data.reason[1].reason[4]` + +SHA-256: `eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"legacy"` | + + + +#### `event:turn/end.data.reason[2]` + +SHA-256: `023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"blocked"` | + + + +#### `event:turn/end.data.reason[3]` + +SHA-256: `79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `error` | 必需 | [`packages/llm/llm/src/types.ts#LlmFailure`](#persistence-type-packagesllmllmsrctypestsllmfailure) | +| `kind` | 必需 | `"error"` | + + + +#### `event:turn/end.data.reason[5]` + +SHA-256: `56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"interrupted"` | + + + +#### `event:turn/start` + +SHA-256: `aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`event:turn/start.data`](#persistence-type-eventturnstartdata) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"turn/start"` | + + + +#### `event:turn/start.data` + +SHA-256: `f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `turn` | 必需 | `number` | + + + +#### `event:user/message` + +SHA-256: `314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/llm/llm/src/message.ts#UserMessage`](#persistence-type-packagesllmllmsrcmessagetsusermessage) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | 必需 | `number` | +| `type` | 必需 | `"user/message"` | + + + +#### `event:web/deepseek-search-llm-request` + +SHA-256: `cf6e3aaf1e2de6480aa0157730a41b9a492108a55304100b0f7e112711dd4331` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `data` | 必需 | [`packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest`](#persistence-type-packageswebweb-search-deepseeksrcprovidertsdeepseeksearchllmrequest) | +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `"web/deepseek-search-llm-request"` | + + + +#### `event:web/deepseek-search-llm-request.data.body` + +SHA-256: `930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731` + +来源:`packages/web/web-search-deepseek/src/provider.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `max_tokens` | 必需 | `number` | +| `messages` | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages) | +| `model` | 必需 | `string` | +| `tools` | 必需 | [`event:web/deepseek-search-llm-request.data.body.tools`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools) | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages` + +SHA-256: `b993441f8ce7d27b80e619e113e232ae8e62d3d5a8340f6bfe12d8c4c018e62f` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0) | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages[0]` + +SHA-256: `9a2a9029f8d7ede05336980d8342737557f487b913bfd28853d0ab5214600ab5` + +来源:`packages/web/web-search-deepseek/src/provider.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages[0].content`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content) | +| `role` | 必需 | `"user"` | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages[0].content` + +SHA-256: `8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) | + + + +#### `event:web/deepseek-search-llm-request.data.body.messages[0].content[0]` + +SHA-256: `4e887768586528565381dadbddee6cef555874148089f4579e0b4b1ad096fc9c` + +来源:`packages/llm/llm/src/types.ts` · `packages/web/web-search-deepseek/src/provider.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `text` | 必需 | `string` | +| `type` | 必需 | `"text"` | + + + +#### `event:web/deepseek-search-llm-request.data.body.tools` + +SHA-256: `4aed17ec726b5397c29f6cb4bcd7905dc1a12bb6140f1657f073cd24380f2af8` + +| 位置 | 存在性 | 类型 | +|---|---|---| +| 0 | 必需 | [`event:web/deepseek-search-llm-request.data.body.tools[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodytools0) | + + + +#### `event:web/deepseek-search-llm-request.data.body.tools[0]` + +SHA-256: `2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3` + +来源:`packages/web/web-search-deepseek/src/provider.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `max_uses` | 必需 | `number` | +| `name` | 必需 | `"web_search"` | +| `type` | 必需 | `"web_search_20250305"` | + + + +#### `"every"` + +SHA-256: `e42b0f40b5d0b628c6e1c44a8fb9eda0780037a81959e1b93d2dfb47b46b0e87` + +`"every"` + + + +#### `"failed"` + +SHA-256: `b57a2889408de36e4516807194c73bdecd51a92f633ccd05db81bf049200f420` + +`"failed"` + + + +#### `"fallback"` + +SHA-256: `d6e654b88b584fcdf290a56802b1730bc7b9847ae86baa4265ab7769eb48990c` + +`"fallback"` + + + +#### `"feedback/message-delete"` + +SHA-256: `44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e` + +`"feedback/message-delete"` + + + +#### `"feedback/message-put"` + +SHA-256: `6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8` + +`"feedback/message-put"` + + + +#### `"feedback/record"` + +SHA-256: `c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954` + +`"feedback/record"` + + + +#### `"file"` + +SHA-256: `277b61f9c6f8170425fa6ffe06cfa14376757a896a4749cb82a687d7364c4fc9` + +`"file"` + + + +#### `"finish"` + +SHA-256: `bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd` + +`"finish"` + + + +#### `"fork"` + +SHA-256: `2da725e554cd89301d829ed9dc45a572c3cd1b93b5e91d0d71f007976d8a0863` + +`"fork"` + + + +#### `"fresh"` + +SHA-256: `dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d` + +`"fresh"` + + + +#### `"goal"` + +SHA-256: `b815d7b91cdd9fc6ccc7dcba05cfc5ce1d55fab5fc0c0801803cd3630cedb602` + +`"goal"` + + + +#### `"goal/change"` + +SHA-256: `237c004c73b6b288246816e0d7fde16e09c63a47aa3b1227383d7afe58666163` + +`"goal/change"` + + + +#### `"hook"` + +SHA-256: `dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc` + +`"hook"` + + + +#### `"hook/invoked"` + +SHA-256: `b9305f0ea75ccd6a6061c27fde19f2ab85534f9f3c1a717b573b077ebae0f611` + +`"hook/invoked"` + + + +#### `"hook/result"` + +SHA-256: `a3a259a1aa5401af786ce08c4a8419681d3000d73467991b5fc563389bc4ebd2` + +`"hook/result"` + + + +#### `"image"` + +SHA-256: `fb8b6a2e53cb9cf44c551176de0fb77d1ddc60037b99a891ff8a860b6d5c29a0` + +`"image"` + + + +#### `"image/gif"` + +SHA-256: `de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048` + +`"image/gif"` + + + +#### `"image/jpeg"` + +SHA-256: `3f74ba74acd10644c1ed6947a411d8088bd2cfac74f61bb8540f96d68e31f004` + +`"image/jpeg"` + + + +#### `"image/offload"` + +SHA-256: `9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49` + +`"image/offload"` + + + +#### `"image/png"` + +SHA-256: `58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0` + +`"image/png"` + + + +#### `"image/webp"` + +SHA-256: `ebb768d85ec87fb68e42fc14fd7d8535b5ac11791b14d04c6770180f0a719bf8` + +`"image/webp"` + + + +#### `"in-history"` + +SHA-256: `f311671e07bc7fa645a0b6597de9966b97147956565296ba76a36543801b66c5` + +来源:`packages/llm/llm/src/types.ts` + +`"in-history"` + + + +#### `"in_progress"` + +SHA-256: `94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378` + +`"in_progress"` + + + +#### `"initial"` + +SHA-256: `e7ce49f12953583fad217bf80fb9f1463acff2c3e9471a823782661675fb124c` + +`"initial"` + + + +#### `"instruction-following"` + +SHA-256: `e4cac694f8b6e1d52e48c699464f1c4c26111ef87e558f7931040d00fdc8d486` + +`"instruction-following"` + + + +#### `"instructions"` + +SHA-256: `fee1caf8ab6a65c1bc981f5a1730164490f22a2a89ffa3d0b76f1f432c44c8b5` + +`"instructions"` + + + +#### `"interrupted"` + +SHA-256: `69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199` + +`"interrupted"` + + + +#### `"legacy"` + +SHA-256: `ad3b56aa2fc1ad4250e7399295d34a8eae592e1907e85852e2291b2e498a30bc` + +`"legacy"` + + + +#### `"llm/retry"` + +SHA-256: `611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d` + +`"llm/retry"` + + + +#### `"llm/retry-started"` + +SHA-256: `4ae007ed190a72c92138b22d059b83208079c7551ca13fb59ae8cf5e23693964` + +`"llm/retry-started"` + + + +#### `"max-tokens"` + +SHA-256: `68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe` + +`"max-tokens"` + + + +#### `"model"` + +SHA-256: `2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e` + +`"model"` + + + +#### `"model/selection"` + +SHA-256: `1d5f04a03ea75fc8eeece544129eba0f49f0c82046e9c404461920390135c7b2` + +`"model/selection"` + + + +#### `"negative"` + +SHA-256: `b1f62380f6746fedd629e71065e3583cef83334875b499ac9665c2eb87acfbf5` + +`"negative"` + + + +#### `"never"` + +SHA-256: `1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b` + +`"never"` + + + +#### `"next-step"` + +SHA-256: `3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693` + +`"next-step"` + + + +#### `"next-turn"` + +SHA-256: `62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd` + +`"next-turn"` + + + +#### `"normal"` + +SHA-256: `3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79` + +`"normal"` + + + +#### `"notice"` + +SHA-256: `e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367` + +`"notice"` + + + +#### `null` + +SHA-256: `938f7c7357bc403ea3b281a9dd016939df7a0880fc8db12612585be574d0d615` + +`null` + + + +#### `number` + +SHA-256: `0657d3ca5ac4e7bf79b00bcf860b1c7159d01a9da137497221ec2f1776e365f7` + +来源:`packages/core/session/src/types.ts` + +`number` + + + +#### `"one-shot"` + +SHA-256: `d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2` + +`"one-shot"` + + + +#### `"other"` + +SHA-256: `9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4` + +`"other"` + + + +#### `packages/api/session-controller/src/types.ts#ModelSelection` + +SHA-256: `f09e5e7acf5ff5ccd193ff2eeec015fa2ff7c29d98bc465f8c3302058d47e29b` + +来源:`packages/api/session-controller/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `reasoningEffort` | 可选 | `string` | + + + +#### `packages/attachment/attachment/src/types.ts#FileAttachmentRef` + +SHA-256: `f19bee84bf3d20904553cdcd57465232bc1c2a194f54c4d195292ba0487223a6` + +来源:`packages/attachment/attachment/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachmentId` | 必需 | `string` | +| `bytes` | 必需 | `number` | +| `name` | 必需 | `string` | + + + +#### `packages/attachment/attachment/src/types.ts#ImageAttachmentRef` + +SHA-256: `b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35` + +来源:`packages/attachment/attachment/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachmentId` | 必需 | `string` | +| `bytes` | 必需 | `number` | +| `height` | 必需 | `number` | +| `mediaType` | 必需 | [`packages/attachment/attachment/src/types.ts#ImageMediaType`](#persistence-type-packagesattachmentattachmentsrctypestsimagemediatype) | +| `name` | 可选 | `string` | +| `originalDimensions` | 可选 | [`event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions`](#persistence-type-eventagentinboxspliceddatainserted0content02attachmentoriginaldimensions) | +| `width` | 必需 | `number` | + + + +#### `packages/attachment/attachment/src/types.ts#ImageMediaType` + +SHA-256: `2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716` + +来源:`packages/attachment/attachment/src/types.ts` + +以下类型之一: + +- `"image/gif"` +- `"image/jpeg"` +- `"image/png"` +- `"image/webp"` + + + +#### `packages/compaction/compaction-image-offload/src/projection.ts#ImageOffloadTarget` + +SHA-256: `1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f` + +来源:`packages/compaction/compaction-image-offload/src/projection.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `imageIndexes` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `seq` | 必需 | `number` | + + + +#### `packages/context/agent-instructions/src/render.ts#AgentInstructionChange` + +SHA-256: `83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239` + +来源:`packages/context/agent-instructions/src/render.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `action` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action`](#persistence-type-eventagentinboxspliceddatainserted0source16changes0action) | +| `digest` | 可选 | `string` | +| `path` | 必需 | `string` | +| `scope` | 必需 | `string` | + + + +#### `packages/context/agent-instructions/src/state.ts#AgentInstructionSource` + +SHA-256: `6f22a9d02b9a1f1157f3b0e7bdccd7e7b12b085c4efdb709dfc74a465cd4e590` + +来源:`packages/context/agent-instructions/src/state.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `baseline` | 可选 | `true` | +| `baselineIdentity` | 可选 | `string` | +| `changes` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[16].changes`](#persistence-type-eventagentinboxspliceddatainserted0source16changes) | +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"agent-instructions"` | + + + +#### `packages/context/session-reference/src/types.ts#SessionReferenceSource` + +SHA-256: `f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f` + +来源:`packages/context/session-reference/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"recall"` | +| `kind` | 必需 | `"session-reference"` | +| `references` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[15].references`](#persistence-type-eventagentinboxspliceddatainserted0source15references) | +| `version` | 必需 | `1` | + + + +#### `packages/core/agent/src/types.ts#InboxTarget` + +SHA-256: `96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c` + +来源:`packages/core/agent/src/types.ts` + +以下类型之一: + +- `"next-step"` +- `"next-turn"` + + + +#### `packages/core/session/src/types.ts#EpochHeader` + +SHA-256: `c55a891c7aac496de6ee64c91c1fb65728c977314013033e42c863428aada854` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `adapterDefaults` | 可选 | [`packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfigadapterdefaults) | +| `config` | 必需 | [`packages/llm/llm/src/call-config.ts#LlmCallConfig`](#persistence-type-packagesllmllmsrccall-configtsllmcallconfig) | +| `tools` | 可选 | [`event:request/header.data.header.tools`](#persistence-type-eventrequestheaderdataheadertools) | + + + +#### `packages/core/session/src/types.ts#RequestContext` + +SHA-256: `b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `contextWindow` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `systemPromptUpdate` | 可选 | `"in-history"` | + + + +#### `packages/core/session/src/types.ts#RequestHeaderReason` + +SHA-256: `530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6` + +来源:`packages/core/session/src/types.ts` + +以下类型之一: + +- `"change"` +- `"initial"` +- `"resume"` +- `"series"` + + + +#### `packages/core/session/src/types.ts#SessionHeader` + +SHA-256: `2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentPreset` | 可选 | `string` | +| `createdAt` | 必需 | `number` | +| `cwd` | 可选 | `string` | +| `delegationDepth` | 可选 | `number` | +| `id` | 必需 | `string` | +| `isSeeded` | 必需 | `boolean` | +| `origin` | 可选 | `"subagent"` | +| `parentSession` | 可选 | `string` | +| `version` | 必需 | `3` | + + + +#### `packages/core/session/src/types.ts#SurfaceOp` + +SHA-256: `335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5` + +来源:`packages/core/session/src/types.ts` + +以下类型之一: + +- `"append"` +- [`SessionEventEnvelope[6].surfaceOp[1]`](#persistence-type-sessioneventenvelope6surfaceop1) + + + +#### `packages/core/session/src/types.ts#TurnEndCancelCause` + +SHA-256: `1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0` + +来源:`packages/core/session/src/types.ts` + +以下类型之一: + +- [`event:turn/end.data.reason[1].reason[2]`](#persistence-type-eventturnenddatareason1reason2) +- [`event:turn/end.data.reason[1].reason[3]`](#persistence-type-eventturnenddatareason1reason3) +- [`event:turn/end.data.reason[1].reason[4]`](#persistence-type-eventturnenddatareason1reason4) +- [`event:turn/end.data.reason[1].reason[1]`](#persistence-type-eventturnenddatareason1reason1) +- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) + + + +#### `packages/core/session/src/types.ts#TurnEndReason` + +SHA-256: `a5a8c15f08af1b0f26f40906e0797b6b0920fd01069e660becce35ab7fc48d77` + +来源:`packages/core/session/src/types.ts` + +以下类型之一: + +- [`event:turn/end.data.reason[5]`](#persistence-type-eventturnenddatareason5) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) +- [`event:turn/end.data.reason[3]`](#persistence-type-eventturnenddatareason3) +- [`event:turn/end.data.reason[1]`](#persistence-type-eventturnenddatareason1) +- [`event:turn/end.data.reason[2]`](#persistence-type-eventturnenddatareason2) +- [`event:turn/end.data.reason[0]`](#persistence-type-eventturnenddatareason0) + + + +#### `packages/core/tools/src/index.ts#ToolRestriction` + +SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f` + +来源:`packages/core/tools/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `allow` | 可选 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `deny` | 可选 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | + + + +#### `packages/core/tools/src/types.ts#PtcDispatchEventData` + +SHA-256: `8d2e5a3c4230e6ea6c0b5151f02241d0db02cd2551f2df1b6b9700cddcc0dca3` + +来源:`packages/core/tools/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `unknown`(不透明) | +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `error` | 可选 | [`event:tool/ptc-dispatch.data.error`](#persistence-type-eventtoolptc-dispatchdataerror) | +| `isError` | 必需 | `boolean` | +| `name` | 必需 | `string` | +| `parentCallId` | 必需 | `string` | +| `rootCallId` | 必需 | `string` | +| `subCallId` | 必需 | `string` | + + + +#### `packages/core/tools/src/types.ts#PtcDispatchStartEventData` + +SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f` + +来源:`packages/core/tools/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `unknown`(不透明) | +| `name` | 必需 | `string` | +| `parentCallId` | 必需 | `string` | +| `rootCallId` | 必需 | `string` | +| `subCallId` | 必需 | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMemberPhase` + +SHA-256: `dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd` + +来源:`packages/experimental/agent-team/src/types.ts` + +以下类型之一: + +- `"active"` +- `"failed"` +- `"provisioning"` + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMemberSnapshot` + +SHA-256: `6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `context` | 必需 | [`event:team/member.data.member.context`](#persistence-type-eventteammemberdatamembercontext) | +| `description` | 必需 | `string` | +| `error` | 可选 | `string` | +| `id` | 必需 | `string` | +| `name` | 必需 | `string` | +| `phase` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamMemberPhase`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammemberphase) | +| `provider` | 必需 | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot` + +SHA-256: `5b694f394d5e11609887a3ccfa82844935d49806c37e336b30be2186d649ab94` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | 必需 | `string` | +| `senderId` | 必需 | `string` | +| `senderName` | 必需 | `string` | +| `targetId` | 必需 | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamMessageSource` + +SHA-256: `2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"team-message"` | +| `messageId` | 必需 | `string` | +| `senderId` | 必需 | `string` | +| `senderName` | 必需 | `string` | +| `teamId` | 必需 | `string` | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamTaskSnapshot` + +SHA-256: `51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357` + +来源:`packages/experimental/agent-team/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blockedBy` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `description` | 必需 | `string` | +| `id` | 必需 | `string` | +| `ownerId` | 可选 | `string` | +| `revision` | 必需 | `number` | +| `status` | 必需 | [`packages/experimental/agent-team/src/types.ts#TeamTaskStatus`](#persistence-type-packagesexperimentalagent-teamsrctypeststeamtaskstatus) | +| `subject` | 必需 | `string` | +| `writeScopes` | 必需 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | + + + +#### `packages/experimental/agent-team/src/types.ts#TeamTaskStatus` + +SHA-256: `b2d2a01e51341a3bfec809198952c8c830a7899f4cb6ecd3c1dc0b5d9a2af943` + +来源:`packages/experimental/agent-team/src/types.ts` + +以下类型之一: + +- `"completed"` +- `"deleted"` +- `"in_progress"` +- `"pending"` + + + +#### `packages/feedback/command-feedback/src/types.ts#FeedbackRecord` + +SHA-256: `7d54a5a5e629e2e7783bfac72683bcc5e969e9f43426b9289826aaf294ff6344` + +来源:`packages/feedback/command-feedback/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `category` | 可选 | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | +| `text` | 可选 | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackDelete` + +SHA-256: `7c6129b6961cf4b2a030f36c78d2b0a5be38617651a9b81322e054ee512bee06` + +来源:`packages/feedback/message-feedback/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `messageId` | 必需 | `string` | +| `sessionId` | 必需 | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem` + +SHA-256: `3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182` + +来源:`packages/feedback/message-feedback/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `category` | 可选 | [`event:feedback/message-put.data.item.category`](#persistence-type-eventfeedbackmessage-putdataitemcategory) | +| `createdAt` | 必需 | `number` | +| `messageId` | 必需 | `string` | +| `note` | 可选 | `string` | +| `rating` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackrating) | +| `updatedAt` | 必需 | `number` | +| `version` | 必需 | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackPut` + +SHA-256: `aa7bc2817014ca6c45719b1c193c5c131be718a0921f34345098ff250f444626` + +来源:`packages/feedback/message-feedback/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `item` | 必需 | [`packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem`](#persistence-type-packagesfeedbackmessage-feedbacksrctypestsmessagefeedbackitem) | +| `sessionId` | 必需 | `string` | + + + +#### `packages/feedback/message-feedback/src/types.ts#MessageFeedbackRating` + +SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2` + +来源:`packages/feedback/message-feedback/src/types.ts` + +以下类型之一: + +- `"negative"` +- `"positive"` + + + +#### `packages/fs/tool-present/src/types.ts#PresentedFile` + +SHA-256: `b8fc636a2121df9d8423c242e03c9d23b7ab7c6fdce00e45746932c60b730f97` + +来源:`packages/fs/tool-present/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `description` | 可选 | `string` | +| `path` | 必需 | `string` | + + + +#### `packages/goal/goal/src/domain.ts#GoalChangeMeta` + +SHA-256: `7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438` + +来源:`packages/goal/goal/src/domain.ts` + +以下类型之一: + +- [`packages/goal/goal/src/domain.ts#GoalClearChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalclearchangemeta) +- [`packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta`](#persistence-type-packagesgoalgoalsrcdomaintsgoalsnapshotchangemeta) + + + +#### `packages/goal/goal/src/domain.ts#GoalClearChangeMeta` + +SHA-256: `cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f` + +来源:`packages/goal/goal/src/domain.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `cleared` | 必需 | [`packages/goal/goal/src/types.ts#GoalRef`](#persistence-type-packagesgoalgoalsrctypestsgoalref) | +| `clearedAt` | 必需 | `number` | +| `kind` | 必需 | `"goal/change"` | +| `operation` | 必需 | `"clear"` | +| `version` | 必需 | `1` | + + + +#### `packages/goal/goal/src/domain.ts#GoalMessageSource` + +SHA-256: `7f959241c24128b4983b559984811861dc59774b85905c8fa57c6cb0148a3dbc` + +来源:`packages/goal/goal/src/domain.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `goalId` | 必需 | `string` | +| `kind` | 必需 | `"goal"` | +| `revision` | 必需 | `number` | +| `round` | 必需 | `number` | + + + +#### `packages/goal/goal/src/domain.ts#GoalSnapshotChangeMeta` + +SHA-256: `1df34a6c086866ffdc2dd9e8e5c581c3751a010cdf6b8538a7327f7a3237f0b4` + +来源:`packages/goal/goal/src/domain.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `createdAt` | 必需 | `number` | +| `goal` | 必需 | [`packages/goal/goal/src/types.ts#GoalSnapshot`](#persistence-type-packagesgoalgoalsrctypestsgoalsnapshot) | +| `kind` | 必需 | `"goal/change"` | +| `operation` | 必需 | [`event:goal/change.data[0].operation`](#persistence-type-eventgoalchangedata0operation) | +| `roundsStarted` | 必需 | `number` | +| `updatedAt` | 必需 | `number` | +| `version` | 必需 | `1` | + + + +#### `packages/goal/goal/src/types.ts#GoalBlockReason` + +SHA-256: `84ac8c1a66ffc697262e181f42e851259eae14038c113ca329fb4700ccdb1f7c` + +来源:`packages/goal/goal/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `code` | 必需 | `string` | +| `message` | 必需 | `string` | + + + +#### `packages/goal/goal/src/types.ts#GoalPhase` + +SHA-256: `b8327af7ee5767952d1300cb4f03b7fc04197ae5ba275e13981c689ff7506172` + +来源:`packages/goal/goal/src/types.ts` + +以下类型之一: + +- `"active"` +- `"blocked"` +- `"complete"` +- `"paused"` + + + +#### `packages/goal/goal/src/types.ts#GoalRef` + +SHA-256: `0b6d718c693fdf7f06dcccb0bcbbabe78cc63514eafc62d6b2a3899735279d6f` + +来源:`packages/goal/goal/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `revision` | 必需 | `number` | + + + +#### `packages/goal/goal/src/types.ts#GoalSnapshot` + +SHA-256: `6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25` + +来源:`packages/goal/goal/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blockedReason` | 可选 | [`packages/goal/goal/src/types.ts#GoalBlockReason`](#persistence-type-packagesgoalgoalsrctypestsgoalblockreason) | +| `id` | 必需 | `string` | +| `maxGoalRounds` | 必需 | `number` | +| `objective` | 必需 | `string` | +| `phase` | 必需 | [`packages/goal/goal/src/types.ts#GoalPhase`](#persistence-type-packagesgoalgoalsrctypestsgoalphase) | +| `revision` | 必需 | `number` | + + + +#### `packages/hooks/hook-protocol/src/types.ts#HookDialect` + +SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` + +来源:`packages/hooks/hook-protocol/src/types.ts` + +以下类型之一: + +- `"claude-code"` +- `"codex"` + + + +#### `packages/interaction/user-approval/src/index.ts#ApprovalPolicy` + +SHA-256: `05d2ae1e0c7f8770f83f9a09047afb39a335d8ac986df3193659aa1e581472cf` + +来源:`packages/interaction/user-approval/src/index.ts` + +以下类型之一: + +- `"ask"` +- `"never"` + + + +#### `packages/interaction/user-approval/src/types.ts#ApprovalOutcome` + +SHA-256: `930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7` + +来源:`packages/interaction/user-approval/src/types.ts` + +以下类型之一: + +- `"allowed-once"` +- `"cancelled"` +- `"rejected"` +- `"unavailable"` + + + +#### `packages/llm/llm-retry/src/types.ts#LlmRetryEventData` + +SHA-256: `c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1` + +来源:`packages/llm/llm-retry/src/types.ts` + +以下类型之一: + +- [`event:llm/retry.data[0]`](#persistence-type-eventllmretrydata0) +- [`event:llm/retry.data[1]`](#persistence-type-eventllmretrydata1) + + + +#### `packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData` + +SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20` + +来源:`packages/llm/llm-retry/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `retry` | 必需 | `number` | +| `retryId` | 必需 | `string` | +| `step` | 必需 | `number` | +| `turn` | 必需 | `number` | + + + +#### `packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord` + +SHA-256: `86cf1e44038cb8b11659863dd0efafe682e41b9c782265c1d50e0a687debfc60` + +来源:`packages/llm/llm/src/assistant-stream.ts` + +以下类型之一: + +- [`event:assistant/attempt.data.stream[0][2]`](#persistence-type-eventassistantattemptdatastream02) +- [`event:assistant/attempt.data.stream[0][3]`](#persistence-type-eventassistantattemptdatastream03) +- [`event:assistant/attempt.data.stream[0][1]`](#persistence-type-eventassistantattemptdatastream01) +- [`event:assistant/attempt.data.stream[0][0]`](#persistence-type-eventassistantattemptdatastream00) + + + +#### `packages/llm/llm/src/call-config.ts#LlmCallConfig` + +SHA-256: `67d5f73ceae82f5265258142ad6cf172de2c1fef93ba551b7f0454e0a93bffe0` + +来源:`packages/llm/llm/src/call-config.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `maxTokens` | 可选 | `number` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `reasoningEffort` | 可选 | `string` | +| `stop` | 可选 | [`event:assistant/attempt.data.stream[0][0].texts`](#persistence-type-eventassistantattemptdatastream00texts) | +| `temperature` | 可选 | `number` | + + + +#### `packages/llm/llm/src/call-config.ts#LlmCallConfigAdapterDefaults` + +SHA-256: `326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693` + +来源:`packages/llm/llm/src/call-config.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `maxTokens` | 可选 | `true` | +| `reasoningEffort` | 可选 | `true` | + + + +#### `packages/llm/llm/src/message.ts#AssistantMessage` + +SHA-256: `e50b0a3ed8e6c80b672e4f855c91984f03b5c3fdd5d475bf171171f391a86c83` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"assistant"` | +| `source` | 必需 | [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) | + + + +#### `packages/llm/llm/src/message.ts#ContextSnapshotSection` + +SHA-256: `86e1e384495ee09ac2d60c9db3610f1f1fddac2d248f6f1d6000e78054680219` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `name` | 必需 | `string` | +| `text` | 必需 | `string` | + + + +#### `packages/llm/llm/src/message.ts#Message` + +SHA-256: `23c7cce57d20589897f4e2bd5898affc6fc611b87cd0cc8b95be1cfdd8b3a7eb` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | 必需 | `string` | +| `role` | 必需 | [`event:session/title-llm-request.data.messages[0].role`](#persistence-type-eventsessiontitle-llm-requestdatamessages0role) | +| `source` | 必需 | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | + + + +#### `packages/llm/llm/src/message.ts#MessageSource` + +SHA-256: `4c965666d5b42116945bc356087cd5e1fd549e6dece560785ed60511059a8283` + +来源:`packages/llm/llm/src/message.ts` + +以下类型之一: + +- [`packages/context/agent-instructions/src/state.ts#AgentInstructionSource`](#persistence-type-packagescontextagent-instructionssrcstatetsagentinstructionsource) +- [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) +- [`event:agent/inbox/spliced.data.inserted[0].source[10]`](#persistence-type-eventagentinboxspliceddatainserted0source10) +- [`event:agent/inbox/spliced.data.inserted[0].source[19]`](#persistence-type-eventagentinboxspliceddatainserted0source19) +- [`packages/skill/tool-skill/src/index.ts#SkillCatalogSource`](#persistence-type-packagesskilltool-skillsrcindextsskillcatalogsource) +- [`packages/skill/skill/src/index.ts#SkillInvocationSource`](#persistence-type-packagesskillskillsrcindextsskillinvocationsource) +- [`event:agent/inbox/spliced.data.inserted[0].source[4]`](#persistence-type-eventagentinboxspliceddatainserted0source4) +- [`event:agent/inbox/spliced.data.inserted[0].source[5]`](#persistence-type-eventagentinboxspliceddatainserted0source5) +- [`event:agent/inbox/spliced.data.inserted[0].source[6]`](#persistence-type-eventagentinboxspliceddatainserted0source6) +- [`event:agent/inbox/spliced.data.inserted[0].source[3]`](#persistence-type-eventagentinboxspliceddatainserted0source3) +- [`event:agent/inbox/spliced.data.inserted[0].source[2]`](#persistence-type-eventagentinboxspliceddatainserted0source2) +- [`event:agent/inbox/spliced.data.inserted[0].source[7]`](#persistence-type-eventagentinboxspliceddatainserted0source7) +- [`packages/context/session-reference/src/types.ts#SessionReferenceSource`](#persistence-type-packagescontextsession-referencesrctypestssessionreferencesource) +- [`packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestssubagentsettledmessagesource) +- [`packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource`](#persistence-type-packagessubagentsubagentsrccontinuation-messagestsagentmessagesource) +- [`packages/goal/goal/src/domain.ts#GoalMessageSource`](#persistence-type-packagesgoalgoalsrcdomaintsgoalmessagesource) +- [`packages/experimental/agent-team/src/types.ts#TeamMessageSource`](#persistence-type-packagesexperimentalagent-teamsrctypeststeammessagesource) +- [`packages/llm/llm/src/message.ts#ModelMessageSource`](#persistence-type-packagesllmllmsrcmessagetsmodelmessagesource) +- [`event:agent/inbox/spliced.data.inserted[0].source[1]`](#persistence-type-eventagentinboxspliceddatainserted0source1) +- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) + + + +#### `packages/llm/llm/src/message.ts#ModelMessageSource` + +SHA-256: `719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `kind` | 必需 | `"model"` | +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | +| `replayState` | 可选 | `unknown`(不透明) | + + + +#### `packages/llm/llm/src/message.ts#SystemMessage` + +SHA-256: `302b01ddddcbb3b16cfa3fba2a5d99f5082a55fbd9dc5c83a179a228b8a6a0ca` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"system"` | +| `source` | 必需 | [`event:system/message.data.message.source`](#persistence-type-eventsystemmessagedatamessagesource) | + + + +#### `packages/llm/llm/src/message.ts#ToolMessageSource` + +SHA-256: `d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `callId` | 必需 | `string` | +| `kind` | 必需 | `"tool"` | + + + +#### `packages/llm/llm/src/message.ts#ToolResultMessage` + +SHA-256: `1b573e2d5c094fa87e2a8bf409ddd4ac5ba92a123085e168de44b9ccdbd5244c` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:tool/result.data.message.content`](#persistence-type-eventtoolresultdatamessagecontent) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"user"` | +| `source` | 必需 | [`packages/llm/llm/src/message.ts#ToolMessageSource`](#persistence-type-packagesllmllmsrcmessagetstoolmessagesource) | + + + +#### `packages/llm/llm/src/message.ts#UserMessage` + +SHA-256: `4de5e7644130ed715ef6b5a4d86a87b30dca4096d1a6683c66acf6f7809379c7` + +来源:`packages/llm/llm/src/message.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `id` | 必需 | `string` | +| `role` | 必需 | `"user"` | +| `source` | 必需 | [`packages/llm/llm/src/message.ts#MessageSource`](#persistence-type-packagesllmllmsrcmessagetsmessagesource) | + + + +#### `packages/llm/llm/src/types.ts#ContentBlock` + +SHA-256: `c7b24be059d34d08929593049a1a81eaa3855166aacfe9d7603c0bc8bb728d56` + +来源:`packages/llm/llm/src/types.ts` + +以下类型之一: + +- [`packages/llm/llm/src/types.ts#ReasoningBlock`](#persistence-type-packagesllmllmsrctypestsreasoningblock) +- [`event:web/deepseek-search-llm-request.data.body.messages[0].content[0]`](#persistence-type-eventwebdeepseek-search-llm-requestdatabodymessages0content0) +- [`packages/llm/llm/src/types.ts#ToolCallBlock`](#persistence-type-packagesllmllmsrctypeststoolcallblock) +- [`packages/llm/llm/src/types.ts#ImageBlock`](#persistence-type-packagesllmllmsrctypestsimageblock) +- [`packages/llm/llm/src/types.ts#FileBlock`](#persistence-type-packagesllmllmsrctypestsfileblock) +- [`packages/llm/llm/src/types.ts#ToolResultBlock`](#persistence-type-packagesllmllmsrctypeststoolresultblock) + + + +#### `packages/llm/llm/src/types.ts#ContentBlockType` + +SHA-256: `757013fff5879d73d5753d8d1120faab56110e88ac3932485ab7e034d9e9ce61` + +来源:`packages/llm/llm/src/types.ts` + +以下类型之一: + +- `"file"` +- `"image"` +- `"reasoning"` +- `"text"` +- `"tool-call"` +- `"tool-result"` + + + +#### `packages/llm/llm/src/types.ts#FileBlock` + +SHA-256: `f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachment` | 必需 | [`packages/attachment/attachment/src/types.ts#FileAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsfileattachmentref) | +| `type` | 必需 | `"file"` | + + + +#### `packages/llm/llm/src/types.ts#FinishReason` + +SHA-256: `5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80` + +来源:`packages/llm/llm/src/types.ts` + +以下类型之一: + +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]`](#persistence-type-eventassistantattemptdatastream03chunk6reason3) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]`](#persistence-type-eventassistantattemptdatastream03chunk6reason4) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]`](#persistence-type-eventassistantattemptdatastream03chunk6reason0) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]`](#persistence-type-eventassistantattemptdatastream03chunk6reason1) +- [`event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]`](#persistence-type-eventassistantattemptdatastream03chunk6reason2) + + + +#### `packages/llm/llm/src/types.ts#ImageBlock` + +SHA-256: `12d5808fac1996b9b3c2afa806e03022252ba2d7b88f835862ae1896591f60c7` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `attachment` | 必需 | [`packages/attachment/attachment/src/types.ts#ImageAttachmentRef`](#persistence-type-packagesattachmentattachmentsrctypestsimageattachmentref) | +| `offloaded` | 可选 | `true` | +| `type` | 必需 | `"image"` | + + + +#### `packages/llm/llm/src/types.ts#LlmFailure` + +SHA-256: `5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `code` | 必需 | `string` | +| `message` | 必需 | `string` | +| `offloadImages` | 可选 | `number` | +| `providerRetryAfterMs` | 可选 | `number` | +| `requestId` | 可选 | `string` | +| `status` | 可选 | `number` | + + + +#### `packages/llm/llm/src/types.ts#ReasoningBlock` + +SHA-256: `814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `text` | 必需 | `string` | +| `type` | 必需 | `"reasoning"` | + + + +#### `packages/llm/llm/src/types.ts#ReplayEnvelope` + +SHA-256: `0acd94fe8794574c9ae72c7855ee16d29c546096d4af760d16d1225385764555` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `blocks` | 可选 | [`event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks`](#persistence-type-eventassistantattemptdatastream03chunk6replaystateblocks) | +| `response` | 必需 | `unknown`(不透明) | + + + +#### `packages/llm/llm/src/types.ts#StreamChunk` + +SHA-256: `071d92b9dac661fcc826c678cf64d188f26fb93aab79c627b11a03acdd34dfca` + +来源:`packages/llm/llm/src/types.ts` + +以下类型之一: + +- [`event:assistant/attempt.data.stream[0][3].chunk[3]`](#persistence-type-eventassistantattemptdatastream03chunk3) +- [`event:assistant/attempt.data.stream[0][3].chunk[4]`](#persistence-type-eventassistantattemptdatastream03chunk4) +- [`event:assistant/attempt.data.stream[0][3].chunk[0]`](#persistence-type-eventassistantattemptdatastream03chunk0) +- [`event:assistant/attempt.data.stream[0][3].chunk[2]`](#persistence-type-eventassistantattemptdatastream03chunk2) +- [`event:assistant/attempt.data.stream[0][3].chunk[1]`](#persistence-type-eventassistantattemptdatastream03chunk1) +- [`event:assistant/attempt.data.stream[0][3].chunk[6]`](#persistence-type-eventassistantattemptdatastream03chunk6) +- [`event:assistant/attempt.data.stream[0][3].chunk[5]`](#persistence-type-eventassistantattemptdatastream03chunk5) + + + +#### `packages/llm/llm/src/types.ts#TokenUsage` + +SHA-256: `fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `cacheReadTokens` | 可选 | `number` | +| `cacheWriteTokens` | 可选 | `number` | +| `inputTokens` | 必需 | `number` | +| `outputTokens` | 必需 | `number` | +| `reasoningTokens` | 可选 | `number` | +| `totalTokens` | 可选 | `number` | + + + +#### `packages/llm/llm/src/types.ts#ToolCallBlock` + +SHA-256: `c1f0f17b6493b85db6453bb30e01b208d703731b25bc1e68e5d4fc72eea9cdea` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `arguments` | 必需 | `string` | +| `id` | 必需 | `string` | +| `name` | 必需 | `string` | +| `type` | 必需 | `"tool-call"` | + + + +#### `packages/llm/llm/src/types.ts#ToolResultBlock` + +SHA-256: `d61574d68558c5a184429e70b04da393dd5460bf5cc3ddef814546e659bd5127` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].content`](#persistence-type-eventagentinboxspliceddatainserted0content) | +| `isError` | 可选 | `boolean` | +| `toolCallId` | 必需 | `string` | +| `type` | 必需 | `"tool-result"` | + + + +#### `packages/llm/llm/src/types.ts#ToolSchema` + +SHA-256: `7f5f2a8618c2ece530a18b1358b890fb57fb8c35705e47b66bff2296f8c6e889` + +来源:`packages/llm/llm/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `description` | 必需 | `string` | +| `name` | 必需 | `string` | +| `parameters` | 必需 | [`event:request/header.data.header.tools[0].parameters`](#persistence-type-eventrequestheaderdataheadertools0parameters) | + + + +#### `packages/sandbox/sandbox/src/index.ts#SandboxMode` + +SHA-256: `fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd` + +来源:`packages/sandbox/sandbox/src/index.ts` + +以下类型之一: + +- `"danger-full-access"` +- `"read-only"` +- `"workspace-write"` + + + +#### `packages/schedule/schedule/src/types.ts#AfterScheduleRecord` + +SHA-256: `27e337d3d6b402b221e50c247a3f518a70d0c474cc60beee15fac3e9c5cbfcbe` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `afterSeconds` | 必需 | `number` | +| `id` | 必需 | `string` | +| `kind` | 必需 | `"after"` | +| `prompt` | 必需 | `string` | +| `scheduledAt` | 必需 | `string` | + + + +#### `packages/schedule/schedule/src/types.ts#AtScheduleRecord` + +SHA-256: `658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `kind` | 必需 | `"at"` | +| `prompt` | 必需 | `string` | +| `scheduledAt` | 必需 | `string` | + + + +#### `packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange` + +SHA-256: `e6063d0451dc02026fd9b54ad3f77c7b1b6392ad3e872a7737ac84e13ca72344` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `acceptedAt` | 必需 | `string` | +| `id` | 必需 | `string` | +| `operation` | 必需 | `"dispatch"` | +| `version` | 必需 | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#EveryScheduleRecord` + +SHA-256: `66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `everySeconds` | 必需 | `number` | +| `id` | 必需 | `string` | +| `kind` | 必需 | `"every"` | +| `prompt` | 必需 | `string` | +| `scheduledAt` | 必需 | `string` | + + + +#### `packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange` + +SHA-256: `8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `operation` | 必需 | `"dispatch"` | +| `version` | 必需 | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleChange` + +SHA-256: `e1d0e52dcd1855ffb803efc18f8f7b776c48d1c25757e8a75c0281fa298c02e1` + +来源:`packages/schedule/schedule/src/types.ts` + +以下类型之一: + +- [`packages/schedule/schedule/src/types.ts#EveryScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestseveryscheduledispatchchange) +- [`packages/schedule/schedule/src/types.ts#ScheduleDeleteChange`](#persistence-type-packagesscheduleschedulesrctypestsscheduledeletechange) +- [`packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange`](#persistence-type-packagesscheduleschedulesrctypestsoneshotscheduledispatchchange) +- [`packages/schedule/schedule/src/types.ts#ScheduleCreateChange`](#persistence-type-packagesscheduleschedulesrctypestsschedulecreatechange) + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleCreateChange` + +SHA-256: `ca6425edd20afe34d0cedc6ad1abad1ad7b32e2fbc4c1d24db53939e80bf887f` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `operation` | 必需 | `"create"` | +| `schedule` | 必需 | [`packages/schedule/schedule/src/types.ts#ScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsschedulerecord) | +| `version` | 必需 | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleDeleteChange` + +SHA-256: `18dc21f12bbac8ade8377e6fbb54179e20c3d955d73fba3244c57fb6bf001df0` + +来源:`packages/schedule/schedule/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `id` | 必需 | `string` | +| `operation` | 必需 | `"delete"` | +| `version` | 必需 | `1` | + + + +#### `packages/schedule/schedule/src/types.ts#ScheduleRecord` + +SHA-256: `d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87` + +来源:`packages/schedule/schedule/src/types.ts` + +以下类型之一: + +- [`packages/schedule/schedule/src/types.ts#AfterScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsafterschedulerecord) +- [`packages/schedule/schedule/src/types.ts#EveryScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestseveryschedulerecord) +- [`packages/schedule/schedule/src/types.ts#AtScheduleRecord`](#persistence-type-packagesscheduleschedulesrctypestsatschedulerecord) + + + +#### `packages/session/session-persistence-jsonl/src/format.ts#HeaderLine` + +SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` + +来源:`packages/session/session-persistence-jsonl/src/format.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentPreset` | 可选 | `string` | +| `createdAt` | 必需 | `number` | +| `cwd` | 可选 | `string` | +| `delegationDepth` | 必需 | `number` | +| `id` | 必需 | `string` | +| `isSeeded` | 必需 | `boolean` | +| `origin` | 可选 | `"subagent"` | +| `parentSession` | 可选 | `string` | +| `type` | 必需 | `"session"` | +| `version` | 必需 | `number` | + + + +#### `packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData` + +SHA-256: `9fe0e77a7816b7fdb4b953ec0e2f0cd7bbd22c5de5c3567e612d1b20eb0992e6` + +来源:`packages/session/session-title-llm/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `maxTokens` | 必需 | `number` | +| `messageSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `messages` | 必需 | [`event:session/title-llm-request.data.messages`](#persistence-type-eventsessiontitle-llm-requestdatamessages) | +| `route` | 必需 | [`packages/session/session-title/src/types.ts#SessionTitleModelIdentity`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlemodelidentity) | +| `system` | 必需 | `string` | +| `titleProvider` | 必需 | `string` | + + + +#### `packages/session/session-title/src/types.ts#SessionTitleEventData` + +SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4` + +来源:`packages/session/session-title/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `messageSeqs` | 必需 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `source` | 必需 | [`packages/session/session-title/src/types.ts#SessionTitleSource`](#persistence-type-packagessessionsession-titlesrctypestssessiontitlesource) | +| `title` | 必需 | `string` | + + + +#### `packages/session/session-title/src/types.ts#SessionTitleModelIdentity` + +SHA-256: `07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235` + +来源:`packages/session/session-title/src/types.ts` · `packages/subagent/tool-subagent/src/model-selection.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `model` | 必需 | `string` | +| `provider` | 必需 | `string` | + + + +#### `packages/session/session-title/src/types.ts#SessionTitleSource` + +SHA-256: `30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f` + +来源:`packages/session/session-title/src/types.ts` + +以下类型之一: + +- [`event:session/title.data.source[1]`](#persistence-type-eventsessiontitledatasource1) +- [`event:session/title.data.source[0]`](#persistence-type-eventsessiontitledatasource0) +- [`event:agent/inbox/spliced.data.inserted[0].source[0]`](#persistence-type-eventagentinboxspliceddatainserted0source0) + + + +#### `packages/skill/skill/src/index.ts#SkillInvocationSource` + +SHA-256: `672c4aa2a9b736e3d6e5da6346d2e2ed5e3573f2d0baafa18e7407c9f3fee3db` + +来源:`packages/skill/skill/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"instructions"` | +| `kind` | 必需 | `"skill-invocation"` | +| `name` | 必需 | `string` | + + + +#### `packages/skill/tool-skill/src/index.ts#SkillCatalogSource` + +SHA-256: `fc2ae6962f9f8801c2b1e414668e1e17cbb7544c4f39381198977a38bd10c093` + +来源:`packages/skill/tool-skill/src/index.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `entries` | 必需 | [`event:agent/inbox/spliced.data.inserted[0].source[17].entries`](#persistence-type-eventagentinboxspliceddatainserted0source17entries) | +| `form` | 必需 | `"catalog"` | +| `kind` | 必需 | `"skill-catalog"` | +| `update` | 可选 | `true` | + + + +#### `packages/subagent/subagent/src/catalog.ts#SubagentCatalogEvent` + +SHA-256: `3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e` + +来源:`packages/subagent/subagent/src/catalog.ts` + +以下类型之一: + +- [`event:subagent/catalog.data[1]`](#persistence-type-eventsubagentcatalogdata1) +- [`event:subagent/catalog.data[0]`](#persistence-type-eventsubagentcatalogdata0) + + + +#### `packages/subagent/subagent/src/continuation-messages.ts#AgentMessageSource` + +SHA-256: `4a9bef9f27a942520cc2279ca7dd3082556e4bff543f66b5c0333e1bbed1cd86` + +来源:`packages/subagent/subagent/src/continuation-messages.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"relay"` | +| `kind` | 必需 | `"agent-message"` | +| `senderSessionId` | 必需 | `string` | + + + +#### `packages/subagent/subagent/src/continuation-messages.ts#SubagentSettledMessageSource` + +SHA-256: `4e97c3d85c0fc817ee58873c38c25a2474abaaa0af4839311b50b68db3b8cf1a` + +来源:`packages/subagent/subagent/src/continuation-messages.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `form` | 必需 | `"notice"` | +| `kind` | 必需 | `"subagent-settled"` | +| `senderSessionId` | 必需 | `string` | +| `summary` | 必需 | `string` | + + + +#### `packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData` + +SHA-256: `6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f` + +来源:`packages/subagent/subagent/src/descriptor.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `agentModel` | 可选 | `string` | +| `agentProvider` | 可选 | `string` | +| `agentReasoningEffort` | 可选 | `string` | +| `label` | 必需 | `string` | +| `mode` | 必需 | `"continuable"` | +| `persona` | 可选 | `string` | +| `provider` | 必需 | `string` | +| `toolFilter` | 可选 | [`packages/core/tools/src/index.ts#ToolRestriction`](#persistence-type-packagescoretoolssrcindextstoolrestriction) | +| `version` | 必需 | `number` | + + + +#### `packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData` + +SHA-256: `5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564` + +来源:`packages/subagent/subagent/src/descriptor.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `label` | 可选 | `string` | +| `mode` | 必需 | `"one-shot"` | +| `provider` | 必需 | `string` | +| `version` | 必需 | `number` | + + + +#### `packages/subagent/subagent/src/descriptor.ts#SubagentDescriptorData` + +SHA-256: `86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde` + +来源:`packages/subagent/subagent/src/descriptor.ts` + +以下类型之一: + +- [`packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortscontinuablesubagentdescriptordata) +- [`packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData`](#persistence-type-packagessubagentsubagentsrcdescriptortsoneshotsubagentdescriptordata) + + + +#### `packages/todo/tool-todo/src/types.ts#TodoItem` + +SHA-256: `a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a` + +来源:`packages/todo/tool-todo/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `content` | 必需 | `string` | +| `status` | 必需 | [`event:todo/write.data.todos[0].status`](#persistence-type-eventtodowritedatatodos0status) | + + + +#### `packages/web/web-search-deepseek/src/provider.ts#DeepSeekSearchLlmRequest` + +SHA-256: `2517ba143a271508d3ca35126d5aca8f7f1facf5aaddce4adf011832042fa2b9` + +来源:`packages/web/web-search-deepseek/src/provider.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `apiVersion` | 必需 | `string` | +| `body` | 必需 | [`event:web/deepseek-search-llm-request.data.body`](#persistence-type-eventwebdeepseek-search-llm-requestdatabody) | +| `endpoint` | 必需 | `string` | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData` + +SHA-256: `c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7` + +来源:`packages/workflow/tool-workflow/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `outcome` | 必需 | [`packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowagentoutcome) | +| `runId` | 必需 | `string` | +| `seq` | 必需 | `number` | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentStartData` + +SHA-256: `9a410ddf56792b2b7cd4a224a2e54dc4dee30a8e8e6b1c2b9a1d19992b217adc` + +来源:`packages/workflow/tool-workflow/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `childId` | 必需 | `string` | +| `label` | 必需 | `string` | +| `phase` | 可选 | `string` | +| `runId` | 必需 | `string` | +| `seq` | 必需 | `number` | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunEndData` + +SHA-256: `7f9365bae9fcb73e1e34061a1acfe0422c1a5fd351848cace9bebbe806f28462` + +来源:`packages/workflow/tool-workflow/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `runId` | 必需 | `string` | +| `stopReason` | 必需 | [`packages/workflow/workflow/src/types.ts#WorkflowStopReason`](#persistence-type-packagesworkflowworkflowsrctypestsworkflowstopreason) | + + + +#### `packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData` + +SHA-256: `a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c` + +来源:`packages/workflow/tool-workflow/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `name` | 必需 | `string` | +| `runId` | 必需 | `string` | + + + +#### `packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome` + +SHA-256: `c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896` + +来源:`packages/workflow/workflow/src/types.ts` + +以下类型之一: + +- `"cancelled"` +- `"completed"` +- `"failed"` + + + +#### `packages/workflow/workflow/src/types.ts#WorkflowStopReason` + +SHA-256: `8465ece5e9d9007c038b357015d849c15262cb0bc25abc59e47692d87ee01a15` + +来源:`packages/workflow/workflow/src/types.ts` + +以下类型之一: + +- `"cancelled"` +- `"completed"` +- `"error"` + + + +#### `"parent"` + +SHA-256: `e6411b09c1d982f789bf741ca74e2bea69df56029847f86a6148e722039ee732` + +`"parent"` + + + +#### `"pause"` + +SHA-256: `1d8798b1a5e8c545ee4dcd2b4e75c0b4c9ffd985e4744c6d1a1aab992f859721` + +`"pause"` + + + +#### `"paused"` + +SHA-256: `c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943` + +`"paused"` + + + +#### `"pending"` + +SHA-256: `234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85` + +`"pending"` + + + +#### `"permission/preset"` + +SHA-256: `ae63d9d1080ed8945031594d93f8d96651d7101b848719cc3e1475875cd3d649` + +`"permission/preset"` + + + +#### `"plan/mode"` + +SHA-256: `f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9` + +`"plan/mode"` + + + +#### `"plugin"` + +SHA-256: `e654d28d1e6c471147310d2fba396d00969cfe6ed9022626d3f2c2312e0b1cbb` + +`"plugin"` + + + +#### `"positive"` + +SHA-256: `df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528` + +`"positive"` + + + +#### `"product-interaction"` + +SHA-256: `0341d4c3dfcd53253cdc1e789d9130d3cd848b6f8b0706bf92f313a68b39ff23` + +`"product-interaction"` + + + +#### `"provider"` + +SHA-256: `e31572180d6b28b73f073ad30ae19d5d82982d3daf984723984e23da1e7c459a` + +`"provider"` + + + +#### `"provisioning"` + +SHA-256: `871bfd6f7bb91061246768d3377f3fd58d6b8ea7c31f44c714ae7ab215650d62` + +`"provisioning"` + + + +#### `"read-only"` + +SHA-256: `12a0cfa619ac4a5fc6c3e8e359c8dae15769edc61497a575935c78d5842f8e42` + +`"read-only"` + + + +#### `"reasoning"` + +SHA-256: `3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c` + +`"reasoning"` + + + +#### `"reasoning-chunks"` + +SHA-256: `688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8` + +`"reasoning-chunks"` + + + +#### `"reasoning-delta"` + +SHA-256: `6f091fe32ab24407236090ca9d710bbaf59bb57466e9f3b8f1f6e4862bc863c6` + +`"reasoning-delta"` + + + +#### `"recall"` + +SHA-256: `383cf73ae4748e5beb281ae74857ba1ffb92ae01075b9fbf51af78b666007a8f` + +`"recall"` + + + +#### `"rejected"` + +SHA-256: `fab35c4520883c0d69e42d079c9f543fc5ac7a2d15b537b5572fcd99059c7018` + +`"rejected"` + + + +#### `"relay"` + +SHA-256: `16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e` + +`"relay"` + + + +#### `"remove"` + +SHA-256: `7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc` + +`"remove"` + + + +#### `"replace"` + +SHA-256: `f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8` + +`"replace"` + + + +#### `"request/context"` + +SHA-256: `70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2` + +`"request/context"` + + + +#### `"request/header"` + +SHA-256: `3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e` + +`"request/header"` + + + +#### `"resource-cost"` + +SHA-256: `5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75` + +`"resource-cost"` + + + +#### `"resume"` + +SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66` + +`"resume"` + + + +#### `"sandbox/mode"` + +SHA-256: `ca085dba2c877feceebf3c62f9d39c6c2a4d2314d97b94b3927a780fe8fe2bb2` + +`"sandbox/mode"` + + + +#### `"schedule/change"` + +SHA-256: `0e7b2a97f54f1afdb8cdfad1635abe9145327db539bfb69b4045c19d8c17755d` + +`"schedule/change"` + + + +#### `"security-privacy-permission"` + +SHA-256: `07eccc9ea2f9b5439d76cc77d5e062936677d43f07a23da749819b0a22ee36b7` + +`"security-privacy-permission"` + + + +#### `"series"` + +SHA-256: `4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f` + +`"series"` + + + +#### `"service-stability"` + +SHA-256: `7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732` + +`"service-stability"` + + + +#### `"session"` + +SHA-256: `e41bdebe246abe17154de7e7a1d81035437eee8d20e7f1edff0d91e2598ad828` + +`"session"` + + + +#### `"session-log-deepseek/delivery-accepted"` + +SHA-256: `47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b` + +`"session-log-deepseek/delivery-accepted"` + + + +#### `"session-reference"` + +SHA-256: `7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71` + +`"session-reference"` + + + +#### `"session/end-seed"` + +SHA-256: `1c2686c0682e7bc51d61117b2652bd4a80707e331aa276d6ef915ae32534a330` + +`"session/end-seed"` + + + +#### `SessionEventEnvelope` + +SHA-256: `5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc` + +以下类型之一: + +- [`SessionEventEnvelope[39]`](#persistence-type-sessioneventenvelope39) +- [`SessionEventEnvelope[6]`](#persistence-type-sessioneventenvelope6) +- [`SessionEventEnvelope[0]`](#persistence-type-sessioneventenvelope0) + + + +#### `SessionEventEnvelope[0]` + +SHA-256: `e3e77b26f0148755a505f5b8ea843a3be117827d4703bb5754d9dc8ddbef521f` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `time` | 必需 | `number` | +| `type` | 必需 | `string` | + + + +#### `SessionEventEnvelope[39]` + +SHA-256: `998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `sourceEventSeqs` | 可选 | [`SessionEventEnvelope[39].sourceEventSeqs`](#persistence-type-sessioneventenvelope39sourceeventseqs) | +| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | 必需 | `number` | +| `type` | 必需 | `string` | + + + +#### `SessionEventEnvelope[39].sourceEventSeqs` + +SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` + +`number` 的数组。 + + + +#### `SessionEventEnvelope[6]` + +SHA-256: `7af85bf70d4eafce63e739adae38ea85501e68df3a0e22f97f3a0be90fd9e4cb` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `ignorable` | 可选 | `true` | +| `seq` | 必需 | `number` | +| `surfaceOp` | 必需 | [`packages/core/session/src/types.ts#SurfaceOp`](#persistence-type-packagescoresessionsrctypestssurfaceop) | +| `time` | 必需 | `number` | +| `type` | 必需 | `string` | + + + +#### `SessionEventEnvelope[6].surfaceOp[1]` + +SHA-256: `bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825` + +来源:`packages/core/session/src/types.ts` + +| 属性 | 存在性 | 类型 | +|---|---|---| +| `endSeq` | 必需 | `number` | +| `op` | 必需 | `"replace"` | +| `startSeq` | 必需 | `number` | + + + +#### `"session/title"` + +SHA-256: `7a651f3b672c52fb615f22c0ce9cb3cc5b22aad92e6bbeefb0808fd7b9233a50` + +`"session/title"` + + + +#### `"session/title-llm-request"` + +SHA-256: `587bb11da730e06aa52b62c087d217d6f8f22459b25f31cb9e1e1baf17944e5e` + +`"session/title-llm-request"` + + + +#### `"set"` + +SHA-256: `b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b` + +`"set"` + + + +#### `"skill-catalog"` + +SHA-256: `6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3` + +`"skill-catalog"` + + + +#### `"skill-invocation"` + +SHA-256: `1922cd79a70806c17758185a6ef0458bc1fb3900363906733421c16414da2509` + +`"skill-invocation"` + + + +#### `"snapshot"` + +SHA-256: `6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912` + +`"snapshot"` + + + +#### `"step/end"` + +SHA-256: `c219efbdfd53b836786202ab4532913d555798f0a8615a4e9629736e3799fb70` + +`"step/end"` + + + +#### `"step/start"` + +SHA-256: `2c64d4bc7264fd3f8bed47e96ab8a593bce05a1e4e1c436dcd244a3b7e0c2a9d` + +`"step/start"` + + + +#### `"stop"` + +SHA-256: `57f3f606ff8b6c84d9c443faace9d1dd10cca0354f37a4f515ef075f7c351b90` + +`"stop"` + + + +#### `string` + +SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` + +来源:`packages/api/session-controller/src/types.ts` · `packages/attachment/attachment/src/brand.ts` · `packages/compaction/compaction/src/brand.ts` · `packages/core/session/src/types.ts` · `packages/experimental/agent-team/src/types.ts` · `packages/feedback/message-feedback/src/types.ts` · `packages/goal/goal/src/types.ts` · `packages/interaction/commands/src/brand.ts` · `packages/interaction/user-approval/src/types.ts` · `packages/llm/llm-retry/src/brand.ts` · `packages/llm/llm/src/brand.ts` · `packages/schedule/schedule/src/types.ts` · `packages/session/session-title/src/index.ts` · `packages/session/session-title/src/types.ts` · `packages/webhook/webhook/src/brand.ts` · `packages/workflow/workflow/src/types.ts` + +`string` + + + +#### `"subagent"` + +SHA-256: `aacda84a69739238aa782eea902d3073017d9d74b9808de2bf5a83c9738cbdc6` + +`"subagent"` + + + +#### `"subagent-settled"` + +SHA-256: `bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a` + +`"subagent-settled"` + + + +#### `"subagent/catalog"` + +SHA-256: `44c8c77aa9aa100b0d74d2deee85474b29faa6eee0ac0f662f7abe9931ddd7f2` + +`"subagent/catalog"` + + + +#### `"subagent/descriptor"` + +SHA-256: `5ebce1317eacd2c148456627a09668e927ee15c204f0643f5ea76b46b54a2647` + +`"subagent/descriptor"` + + + +#### `"subagent/model-selection-policy"` + +SHA-256: `0a8a062bc9c3c0d97fd97742262f2ea53dd32297f834e81114870d38ac3dc6da` + +`"subagent/model-selection-policy"` + + + +#### `"success"` + +SHA-256: `511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7` + +`"success"` + + + +#### `"system"` + +SHA-256: `8af841fc9b265ade3441caf9fe40dd24db24226befba48150e6d0eeccc1389c3` + +`"system"` + + + +#### `"system/message"` + +SHA-256: `1c5a58f4599bd4a9711712551ffe2442a5e5fcd0758bafe630cc4ead850bdaa7` + +`"system/message"` + + + +#### `"task-result"` + +SHA-256: `f05fb85e715af4ab4de0b6ba111166dd0435bd8bb74a0fa0f32b9d174113fc7c` + +`"task-result"` + + + +#### `"team-message"` + +SHA-256: `2e4debca12f2c449f96dc6574f3fbf2fb346193443114a241d01a236362ec48c` + +`"team-message"` + + + +#### `"team/member"` + +SHA-256: `18fcdd273a2f2f9d813a3be5e71df5903a963a5c88e46b90b14de6e2db890da0` + +`"team/member"` + + + +#### `"team/message/delivered"` + +SHA-256: `a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57` + +`"team/message/delivered"` + + + +#### `"team/message/queued"` + +SHA-256: `4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159` + +`"team/message/queued"` + + + +#### `"team/task"` + +SHA-256: `b57ae1b37e52bee0a21cbdace168dc6a15582bcda8c306dad962c5dcc8a8e28b` + +`"team/task"` + + + +#### `"text"` + +SHA-256: `4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d` + +`"text"` + + + +#### `"text-chunks"` + +SHA-256: `f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3` + +`"text-chunks"` + + + +#### `"text-delta"` + +SHA-256: `5abab3a27fd2736660ecddd94b28d6bbf114986dd894880153bd1be3ccacb563` + +`"text-delta"` + + + +#### `"todo/write"` + +SHA-256: `af0750d32d97d47b12b7361a587db41894b17e04c9a805fe212f0114aa2248c7` + +`"todo/write"` + + + +#### `"tool"` + +SHA-256: `a13d8f379222ece8a02a86efe4c8334af4f108ecb3034b38c0a42bb3046e6847` + +`"tool"` + + + +#### `"tool-call"` + +SHA-256: `1f0133217eeeffd8d387baf1ec8ed9856e719bcd999dc08e48624cba96d75fd7` + +`"tool-call"` + + + +#### `"tool-call-chunks"` + +SHA-256: `616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5` + +`"tool-call-chunks"` + + + +#### `"tool-call-delta"` + +SHA-256: `9b4fd974c124c83743efe030ba4e1250e087505f3f74588716a521fb8d453267` + +`"tool-call-delta"` + + + +#### `"tool-calls"` + +SHA-256: `6c1cccb433ddc153facb380c7dda956237ba5c31f8a532a69142dc277890cc9b` + +`"tool-calls"` + + + +#### `"tool-result"` + +SHA-256: `e5244812c495a80c2e78ba2c2690dca5f6b58ea8d3fe5531ff94a6f9ac5e5d66` + +`"tool-result"` + + + +#### `"tool-workflow/agent-end"` + +SHA-256: `5d17f27a1ef9f7026c0232714adf7573961536d75f3303ca97973975f5af170e` + +`"tool-workflow/agent-end"` + + + +#### `"tool-workflow/agent-start"` + +SHA-256: `ad92f473a03ae72599ff26c86e897c25e16269519ad2a87340f0bea946517af8` + +`"tool-workflow/agent-start"` + + + +#### `"tool-workflow/run-end"` + +SHA-256: `fe792a6cd430494503837e21e79f91677704ccdd9e870c679aabd7d43ed47ddd` + +`"tool-workflow/run-end"` + + + +#### `"tool-workflow/run-start"` + +SHA-256: `cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670` + +`"tool-workflow/run-start"` + + + +#### `"tool/call"` + +SHA-256: `c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92` + +`"tool/call"` + + + +#### `"tool/ptc-dispatch"` + +SHA-256: `fb5e0517050d2c6d40e5b8145db1f7c5ca7044d5d50fada6ff80e0b22c6ca973` + +`"tool/ptc-dispatch"` + + + +#### `"tool/ptc-dispatch-start"` + +SHA-256: `2aed07493b1c65b6d00de5586da1e743cf501684b9ad43a1765fb4007d4ea456` + +`"tool/ptc-dispatch-start"` + + + +#### `"tool/result"` + +SHA-256: `570e85022434613394418ad33e77e9f1f7a05699b33d0b62eae0677a638c3833` + +`"tool/result"` + + + +#### `true` + +SHA-256: `dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521` + +`true` + + + +#### `"turn/end"` + +SHA-256: `4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03` + +`"turn/end"` + + + +#### `"turn/start"` + +SHA-256: `0af3ecfb8c60d416fc40a7cc4fb2c4851a8e46608b2b38ab9e510670c971aa1f` + +`"turn/start"` + + + +#### `"unavailable"` + +SHA-256: `2c4c21f19f426a58f2dac914e34313aa43f8408972de857a486d1f086d5adb6c` + +`"unavailable"` + + + +#### `unknown` + +SHA-256: `bbc5696e3f13c758237b316e3cf08cda0b9fd51ffe672539883457769faa185d` + +`unknown`:此声明未暴露存储值的内部字段。 + + + +#### `"usage"` + +SHA-256: `0bdaf9cb63594be4ef034b68901fffe792fe09d6d5f6bac42d7f56f6e7834fb9` + +`"usage"` + + + +#### `"user"` + +SHA-256: `68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573` + +`"user"` + + + +#### `"user/message"` + +SHA-256: `de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f` + +`"user/message"` + + + +#### `"web_search"` + +SHA-256: `935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682` + +`"web_search"` + + + +#### `"web_search_20250305"` + +SHA-256: `0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e` + +`"web_search_20250305"` + + + +#### `"web/deepseek-search-llm-request"` + +SHA-256: `6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675` + +`"web/deepseek-search-llm-request"` + + + +#### `"webhook"` + +SHA-256: `db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0` + +`"webhook"` + + + +#### `"workspace-write"` + +SHA-256: `a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa` + +`"workspace-write"` + +
+ + + + +## 验证与限制 + +`pnpm run verify-persistence-catalog` 通过后,`pnpm run verify-persistence-formats --archive 3` 从当前 V3 目录创建了 schema。归档保留每个根及其可达的声明类型、根摘要与不透明声明,并移除源码行号。更早的格式记录保持不变。 + +目录记录声明字段与可选性,并不覆盖每项 codec 或恢复不变量。外部插件载荷、物理范围编码与运行时关系需要各自的验证器;schema 完整性本身不能确立迁移安全性。 + +```sh +pnpm run verify-persistence-formats +``` + +该检查仅使用本工作树验证直到当前写入器的每个格式、schema 完整性、双语声明与生成表格。它不会回放历史应用。维护规则参见[格式索引](README.zh.md),当前声明参见[当前目录](../../persistence-catalog.zh.md)。 + + +## 开发备注 + +无。 diff --git a/docs/persistence-changes/releases/dsh-v0.1.5-alpha.2.schema.json b/docs/persistence-changes/releases/dsh-v0.1.5-alpha.2.schema.json index ffabdff76f..e1699a5517 100644 --- a/docs/persistence-changes/releases/dsh-v0.1.5-alpha.2.schema.json +++ b/docs/persistence-changes/releases/dsh-v0.1.5-alpha.2.schema.json @@ -794,7 +794,7 @@ "event:deliverables/presented.data" ], "sources": [ - "packages/deliverables/tool-present/src/types.ts" + "packages/fs/tool-present/src/types.ts" ] }, { @@ -2024,10 +2024,10 @@ ] }, "names": [ - "packages/deliverables/tool-present/src/types.ts#PresentedFile" + "packages/fs/tool-present/src/types.ts#PresentedFile" ], "sources": [ - "packages/deliverables/tool-present/src/types.ts" + "packages/fs/tool-present/src/types.ts" ] }, { diff --git a/docs/persistence-schema.json b/docs/persistence-schema.json index 8649288be2..428d512264 100644 --- a/docs/persistence-schema.json +++ b/docs/persistence-schema.json @@ -1,10 +1,10 @@ { - "formatVersion": 1, + "formatVersion": 2, "roots": [ { "key": "SessionHeader", "kind": "header", - "digest": "2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03", + "digest": "1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445", "schema": { "root": 0, "nodes": [ @@ -77,7 +77,7 @@ }, { "kind": "literal", - "value": 3 + "value": 4 } ] } @@ -406,7 +406,7 @@ "kind": "event", "event": "agent/inbox/spliced", "surface": false, - "digest": "646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f", + "digest": "1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c", "schema": { "root": 0, "nodes": [ @@ -420,22 +420,22 @@ }, { "name": "ignorable", - "type": 18, + "type": 27, "optional": true }, { "name": "seq", - "type": 11, + "type": 20, "optional": false }, { "name": "time", - "type": 11, + "type": 20, "optional": false }, { "name": "type", - "type": 90, + "type": 199, "optional": false } ], @@ -451,22 +451,22 @@ }, { "name": "outcome", - "type": 86, + "type": 195, "optional": true }, { "name": "removedCount", - "type": 11, + "type": 20, "optional": true }, { "name": "start", - "type": 11, + "type": 20, "optional": false }, { "name": "target", - "type": 87, + "type": 196, "optional": false } ], @@ -491,13 +491,23 @@ }, { "name": "role", - "type": 30, + "type": 32, "optional": false }, { "name": "source", - "type": 31, - "optional": false + "type": 33, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } } ], "indices": [] @@ -511,12 +521,106 @@ "types": [ 6, 9, - 20, - 23, - 26, - 28 + 11, + 14, + 16, + 18, + 29 ] }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "object", "properties": [ @@ -537,16 +641,12 @@ }, { "name": "type", - "type": 8, + "type": 17, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "string" - }, { "kind": "literal", "value": "tool-call" @@ -556,17 +656,17 @@ "properties": [ { "name": "attachment", - "type": 10, + "type": 19, "optional": false }, { "name": "offloaded", - "type": 18, + "type": 27, "optional": true }, { "name": "type", - "type": 19, + "type": 28, "optional": false } ], @@ -582,17 +682,17 @@ }, { "name": "bytes", - "type": 11, + "type": 20, "optional": false }, { "name": "height", - "type": 11, + "type": 20, "optional": false }, { "name": "mediaType", - "type": 12, + "type": 21, "optional": false }, { @@ -602,12 +702,12 @@ }, { "name": "originalDimensions", - "type": 17, + "type": 26, "optional": true }, { "name": "width", - "type": 11, + "type": 20, "optional": false } ], @@ -620,12 +720,16 @@ { "kind": "union", "types": [ - 13, - 14, - 15, - 16 + 22, + 23, + 24, + 25 ] }, + { + "kind": "literal", + "value": "image/gif" + }, { "kind": "literal", "value": "image/jpeg" @@ -638,21 +742,17 @@ "kind": "literal", "value": "image/webp" }, - { - "kind": "literal", - "value": "image/gif" - }, { "kind": "object", "properties": [ { "name": "height", - "type": 11, + "type": 20, "optional": false }, { "name": "width", - "type": 11, + "type": 20, "optional": false } ], @@ -671,12 +771,12 @@ "properties": [ { "name": "attachment", - "type": 21, + "type": 30, "optional": false }, { "name": "type", - "type": 22, + "type": 31, "optional": false } ], @@ -692,7 +792,7 @@ }, { "name": "bytes", - "type": 11, + "type": 20, "optional": false }, { @@ -707,80 +807,6 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, { "kind": "literal", "value": "user" @@ -788,189 +814,128 @@ { "kind": "union", "types": [ - 32, + 34, + 37, + 39, 41, 43, - 44, + 45, 47, + 50, 52, 54, - 59, + 56, + 58, 60, - 61, + 62, 63, + 64, 65, 66, + 67, + 68, + 70, + 71, + 72, 73, + 74, 75, + 76, 77, + 78, 79, + 80, 81, + 82, 84, - 85 + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 112, + 114, + 117, + 118, + 119, + 120, + 121, + 123, + 124, + 125, + 126, + 128, + 129, + 130, + 131, + 132, + 134, + 135, + 136, + 138, + 139, + 147, + 149, + 150, + 152, + 154, + 158, + 160, + 168, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 186, + 188, + 189, + 190, + 191, + 192, + 193, + 194 ] }, { "kind": "object", "properties": [ - { - "name": "baseline", - "type": 18, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 7, - "optional": true - }, - { - "name": "changes", - "type": 33, - "optional": false - }, { "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 34 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", "type": 35, "optional": false }, - { - "name": "digest", - "type": 7, - "optional": true - }, - { - "name": "path", - "type": 7, - "optional": false - }, - { - "name": "scope", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 36, - 37, - 38 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 7, - "optional": false - }, { "name": "kind", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 7, - "optional": true - }, - { - "name": "kind", - "type": 30, - "optional": false - }, - { - "name": "rpcId", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 7, - "optional": false - }, - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 46, - "optional": false - }, - { - "name": "provider", - "type": 7, - "optional": false - }, - { - "name": "ruleId", - "type": 7, - "optional": false - }, - { - "name": "source", - "type": 7, + "type": 36, "optional": false }, { @@ -987,157 +952,19 @@ }, { "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 48, - "optional": false - }, - { - "name": "form", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - }, - { - "name": "update", - "type": 18, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 49 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" + "value": "time-context" }, { "kind": "object", "properties": [ { "name": "form", - "type": 39, + "type": 35, "optional": false }, { "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 55, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - }, - { - "name": "sections", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 58 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "text", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, + "type": 38, "optional": false }, { @@ -1148,43 +975,361 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "tmux-context" + }, { "kind": "object", "properties": [ { "name": "form", - "type": 39, + "type": 35, "optional": false }, { "name": "kind", - "type": 56, + "type": 40, "optional": false }, { - "name": "plugin", + "name": "summary", "type": 7, "optional": false } ], "indices": [] }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, { "kind": "object", "properties": [ { "name": "form", - "type": 62, + "type": 48, "optional": false }, { "name": "kind", - "type": 56, + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, "optional": false }, { - "name": "plugin", - "type": 7, + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 49, "optional": false } ], @@ -1199,17 +1344,204 @@ "properties": [ { "name": "form", - "type": 64, + "type": 69, "optional": false }, { "name": "kind", - "type": 56, + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, "optional": false }, { - "name": "plugin", - "type": 7, + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 49, "optional": false } ], @@ -1224,17 +1556,12 @@ "properties": [ { "name": "form", - "type": 50, + "type": 83, "optional": false }, { "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, + "type": 51, "optional": false } ], @@ -1245,157 +1572,188 @@ "properties": [ { "name": "form", - "type": 62, + "type": 83, "optional": false }, { "name": "kind", - "type": 67, - "optional": false - }, - { - "name": "references", - "type": 68, - "optional": false - }, - { - "name": "version", - "type": 72, + "type": 53, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 69 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 11, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 70, - "optional": false - }, - { - "name": "compacted", - "type": 24, - "optional": false - }, - { - "name": "inputIndex", - "type": 11, - "optional": false - }, - { - "name": "label", - "type": 7, - "optional": false - }, - { - "name": "omittedBytes", - "type": 11, - "optional": false - }, - { - "name": "omittedMessages", - "type": 11, - "optional": false - }, - { - "name": "originalMessages", - "type": 11, - "optional": false - }, - { - "name": "retainedMessages", - "type": 11, - "optional": false - }, - { - "name": "sessionId", - "type": 7, - "optional": false - }, - { - "name": "truncated", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 11, - 71 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, { "kind": "object", "properties": [ { "name": "form", - "type": 45, + "type": 83, "optional": false }, { "name": "kind", - "type": 74, - "optional": false - }, - { - "name": "senderSessionId", - "type": 7, - "optional": false - }, - { - "name": "summary", - "type": 7, + "type": 55, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "subagent-settled" - }, { "kind": "object", "properties": [ { "name": "form", - "type": 64, + "type": 83, "optional": false }, { "name": "kind", - "type": 76, + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, "optional": false }, { - "name": "senderSessionId", - "type": 7, + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 49, "optional": false } ], @@ -1403,7 +1761,199 @@ }, { "kind": "literal", - "value": "agent-message" + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] }, { "kind": "object", @@ -1415,17 +1965,17 @@ }, { "name": "kind", - "type": 78, + "type": 111, "optional": false }, { "name": "revision", - "type": 11, + "type": 20, "optional": false }, { "name": "round", - "type": 11, + "type": 20, "optional": false } ], @@ -1440,7 +1990,7 @@ "properties": [ { "name": "kind", - "type": 80, + "type": 113, "optional": false }, { @@ -1475,7 +2025,7 @@ "properties": [ { "name": "kind", - "type": 82, + "type": 115, "optional": false }, { @@ -1490,7 +2040,7 @@ }, { "name": "replayState", - "type": 83, + "type": 116, "optional": true } ], @@ -1509,12 +2059,7 @@ "properties": [ { "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, + "type": 49, "optional": false } ], @@ -1525,7 +2070,1083 @@ "properties": [ { "name": "kind", - "type": 30, + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 122, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 127, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 133, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 137, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 27, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 140, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 141 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 142, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 143, + 144, + 145 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 155, + "optional": false + }, + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 157, + "optional": false + }, + { + "name": "update", + "type": 27, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "references", + "type": 162, + "optional": false + }, + { + "name": "version", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 163 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 20, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 164, + "optional": false + }, + { + "name": "compacted", + "type": 166, + "optional": false + }, + { + "name": "inputIndex", + "type": 20, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 20, + "optional": false + }, + { + "name": "omittedMessages", + "type": 20, + "optional": false + }, + { + "name": "originalMessages", + "type": 20, + "optional": false + }, + { + "name": "retainedMessages", + "type": 20, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 166, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 165 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 171 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 185, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 187, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "summary", + "type": 7, "optional": false } ], @@ -1538,8 +3159,8 @@ { "kind": "union", "types": [ - 88, - 89 + 197, + 198 ] }, { @@ -1837,7 +3458,7 @@ "kind": "event", "event": "assistant/attempt", "surface": false, - "digest": "c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e", + "digest": "15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4", "schema": { "root": 0, "nodes": [ @@ -1866,7 +3487,7 @@ }, { "name": "type", - "type": 72, + "type": 73, "optional": false } ], @@ -1906,8 +3527,8 @@ "types": [ 5, 10, - 68, - 70 + 69, + 71 ] }, { @@ -1982,7 +3603,7 @@ }, { "name": "type", - "type": 67, + "type": 68, "optional": false } ], @@ -1993,11 +3614,11 @@ "types": [ 12, 14, - 40, - 43, - 45, - 47, - 64 + 41, + 44, + 46, + 48, + 65 ] }, { @@ -2050,7 +3671,7 @@ }, { "name": "type", - "type": 39, + "type": 40, "optional": false } ], @@ -2063,8 +3684,9 @@ 18, 28, 31, + 33, 35, - 37 + 38 ] }, { @@ -2249,44 +3871,6 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 32, - "optional": false - }, - { - "name": "isError", - "type": 33, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 34, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 15 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, { "kind": "object", "properties": [ @@ -2297,7 +3881,7 @@ }, { "name": "type", - "type": 36, + "type": 32, "optional": false } ], @@ -2317,7 +3901,7 @@ }, { "name": "type", - "type": 38, + "type": 34, "optional": false } ], @@ -2327,6 +3911,55 @@ "kind": "literal", "value": "text" }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 36, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "literal", "value": "block-end" @@ -2336,7 +3969,7 @@ "properties": [ { "name": "blockType", - "type": 41, + "type": 42, "optional": false }, { @@ -2346,7 +3979,7 @@ }, { "name": "type", - "type": 42, + "type": 43, "optional": false } ], @@ -2358,9 +3991,10 @@ 17, 27, 30, + 32, 34, - 36, - 38 + 37, + 39 ] }, { @@ -2382,7 +4016,7 @@ }, { "name": "type", - "type": 44, + "type": 45, "optional": false } ], @@ -2407,7 +4041,7 @@ }, { "name": "type", - "type": 46, + "type": 47, "optional": false } ], @@ -2422,17 +4056,17 @@ "properties": [ { "name": "reason", - "type": 48, + "type": 49, "optional": false }, { "name": "replayState", - "type": 60, + "type": 61, "optional": true }, { "name": "type", - "type": 63, + "type": 64, "optional": false } ], @@ -2441,11 +4075,11 @@ { "kind": "union", "types": [ - 49, - 52, - 54, - 56, - 58 + 50, + 53, + 55, + 57, + 59 ] }, { @@ -2453,12 +4087,12 @@ "properties": [ { "name": "failure", - "type": 50, + "type": 51, "optional": false }, { "name": "kind", - "type": 51, + "type": 52, "optional": false } ], @@ -2509,12 +4143,12 @@ "properties": [ { "name": "failure", - "type": 50, + "type": 51, "optional": false }, { "name": "kind", - "type": 53, + "type": 54, "optional": false } ], @@ -2529,7 +4163,7 @@ "properties": [ { "name": "kind", - "type": 55, + "type": 56, "optional": false } ], @@ -2544,7 +4178,7 @@ "properties": [ { "name": "kind", - "type": 57, + "type": 58, "optional": false } ], @@ -2559,7 +4193,7 @@ "properties": [ { "name": "kind", - "type": 59, + "type": 60, "optional": false } ], @@ -2574,12 +4208,12 @@ "properties": [ { "name": "blocks", - "type": 61, + "type": 62, "optional": true }, { "name": "response", - "type": 62, + "type": 63, "optional": false } ], @@ -2587,7 +4221,7 @@ }, { "kind": "array", - "element": 62 + "element": 63 }, { "kind": "opaque", @@ -2602,12 +4236,12 @@ "properties": [ { "name": "type", - "type": 65, + "type": 66, "optional": false }, { "name": "usage", - "type": 66, + "type": 67, "optional": false } ], @@ -2682,7 +4316,7 @@ }, { "name": "type", - "type": 69, + "type": 70, "optional": false } ], @@ -2717,7 +4351,7 @@ }, { "name": "type", - "type": 71, + "type": 72, "optional": false } ], @@ -2739,7 +4373,7 @@ "kind": "event", "event": "assistant/message", "surface": true, - "digest": "1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d", + "digest": "1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625", "schema": { "root": 0, "nodes": [ @@ -2763,7 +4397,7 @@ }, { "name": "surfaceOp", - "type": 76, + "type": 78, "optional": false }, { @@ -2773,7 +4407,7 @@ }, { "name": "type", - "type": 80, + "type": 82, "optional": false } ], @@ -2799,7 +4433,7 @@ }, { "name": "stream", - "type": 33, + "type": 35, "optional": false }, { @@ -2809,7 +4443,7 @@ }, { "name": "usage", - "type": 70, + "type": 72, "optional": true } ], @@ -2834,12 +4468,12 @@ }, { "name": "role", - "type": 29, + "type": 31, "optional": false }, { "name": "source", - "type": 30, + "type": 32, "optional": false } ], @@ -2856,8 +4490,9 @@ 9, 19, 22, - 25, - 27 + 24, + 26, + 29 ] }, { @@ -3046,40 +4681,6 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "isError", - "type": 23, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, { "kind": "object", "properties": [ @@ -3090,7 +4691,7 @@ }, { "name": "type", - "type": 26, + "type": 23, "optional": false } ], @@ -3110,7 +4711,7 @@ }, { "name": "type", - "type": 28, + "type": 25, "optional": false } ], @@ -3120,6 +4721,55 @@ "kind": "literal", "value": "text" }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "literal", "value": "assistant" @@ -3129,7 +4779,7 @@ "properties": [ { "name": "kind", - "type": 31, + "type": 33, "optional": false }, { @@ -3144,7 +4794,7 @@ }, { "name": "replayState", - "type": 32, + "type": 34, "optional": true } ], @@ -3160,15 +4810,15 @@ }, { "kind": "array", - "element": 34 + "element": 36 }, { "kind": "union", "types": [ - 35, - 39, - 72, - 74 + 37, + 41, + 74, + 76 ] }, { @@ -3176,12 +4826,12 @@ "properties": [ { "name": "args", - "type": 36, + "type": 38, "optional": false }, { "name": "dt", - "type": 37, + "type": 39, "optional": false }, { @@ -3206,7 +4856,7 @@ }, { "name": "type", - "type": 38, + "type": 40, "optional": false } ], @@ -3229,7 +4879,7 @@ "properties": [ { "name": "chunk", - "type": 40, + "type": 42, "optional": false }, { @@ -3239,7 +4889,7 @@ }, { "name": "type", - "type": 71, + "type": 73, "optional": false } ], @@ -3248,13 +4898,13 @@ { "kind": "union", "types": [ - 41, 43, 45, - 48, + 47, 50, 52, - 68 + 54, + 70 ] }, { @@ -3282,7 +4932,7 @@ }, { "name": "type", - "type": 42, + "type": 44, "optional": false } ], @@ -3307,7 +4957,7 @@ }, { "name": "type", - "type": 44, + "type": 46, "optional": false } ], @@ -3322,7 +4972,7 @@ "properties": [ { "name": "blockType", - "type": 46, + "type": 48, "optional": false }, { @@ -3330,42 +4980,6 @@ "type": 11, "optional": false }, - { - "name": "type", - "type": 47, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 8, - 18, - 21, - 24, - 26, - 28 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 11, - "optional": false - }, - { - "name": "text", - "type": 7, - "optional": false - }, { "name": "type", "type": 49, @@ -3374,9 +4988,21 @@ ], "indices": [] }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 23, + 25, + 28, + 30 + ] + }, { "kind": "literal", - "value": "reasoning-delta" + "value": "block-start" }, { "kind": "object", @@ -3399,6 +5025,31 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 53, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "text-delta" @@ -3408,17 +5059,17 @@ "properties": [ { "name": "reason", - "type": 53, + "type": 55, "optional": false }, { "name": "replayState", - "type": 65, + "type": 67, "optional": true }, { "name": "type", - "type": 67, + "type": 69, "optional": false } ], @@ -3427,11 +5078,11 @@ { "kind": "union", "types": [ - 54, - 57, + 56, 59, 61, - 63 + 63, + 65 ] }, { @@ -3439,12 +5090,12 @@ "properties": [ { "name": "failure", - "type": 55, + "type": 57, "optional": false }, { "name": "kind", - "type": 56, + "type": 58, "optional": false } ], @@ -3495,12 +5146,12 @@ "properties": [ { "name": "failure", - "type": 55, + "type": 57, "optional": false }, { "name": "kind", - "type": 58, + "type": 60, "optional": false } ], @@ -3515,7 +5166,7 @@ "properties": [ { "name": "kind", - "type": 60, + "type": 62, "optional": false } ], @@ -3530,7 +5181,7 @@ "properties": [ { "name": "kind", - "type": 62, + "type": 64, "optional": false } ], @@ -3545,7 +5196,7 @@ "properties": [ { "name": "kind", - "type": 64, + "type": 66, "optional": false } ], @@ -3560,12 +5211,12 @@ "properties": [ { "name": "blocks", - "type": 66, + "type": 68, "optional": true }, { "name": "response", - "type": 32, + "type": 34, "optional": false } ], @@ -3573,7 +5224,7 @@ }, { "kind": "array", - "element": 32 + "element": 34 }, { "kind": "literal", @@ -3584,12 +5235,12 @@ "properties": [ { "name": "type", - "type": 69, + "type": 71, "optional": false }, { "name": "usage", - "type": 70, + "type": 72, "optional": false } ], @@ -3644,7 +5295,7 @@ "properties": [ { "name": "dt", - "type": 37, + "type": 39, "optional": false }, { @@ -3654,42 +5305,7 @@ }, { "name": "texts", - "type": 36, - "optional": false - }, - { - "name": "time0", - "type": 11, - "optional": false - }, - { - "name": "type", - "type": 73, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 37, - "optional": false - }, - { - "name": "index", - "type": 11, - "optional": false - }, - { - "name": "texts", - "type": 36, + "type": 38, "optional": false }, { @@ -3705,6 +5321,41 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 39, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 38, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 77, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "text-chunks" @@ -3712,8 +5363,8 @@ { "kind": "union", "types": [ - 77, - 79 + 79, + 81 ] }, { @@ -3726,7 +5377,7 @@ }, { "name": "op", - "type": 78, + "type": 80, "optional": false }, { @@ -4240,7 +5891,7 @@ "kind": "event", "event": "compaction/summary", "surface": false, - "digest": "f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59", + "digest": "e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602", "schema": { "root": 0, "nodes": [ @@ -4269,7 +5920,7 @@ }, { "name": "type", - "type": 33, + "type": 35, "optional": false } ], @@ -4279,7 +5930,7 @@ "kind": "union", "types": [ 2, - 32 + 34 ] }, { @@ -4317,12 +5968,12 @@ }, { "name": "shadowedRange", - "type": 29, + "type": 31, "optional": false }, { "name": "shadowedSeqs", - "type": 30, + "type": 32, "optional": false }, { @@ -4342,7 +5993,7 @@ }, { "name": "usage", - "type": 31, + "type": 33, "optional": true } ], @@ -4368,47 +6019,14 @@ "kind": "union", "types": [ 8, - 11, - 13, + 10, + 12, 15, 17, - 26 + 19, + 28 ] }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 6, - "optional": false - }, - { - "name": "isError", - "type": 9, - "optional": true - }, - { - "name": "toolCallId", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, { "kind": "object", "properties": [ @@ -4419,7 +6037,7 @@ }, { "name": "type", - "type": 12, + "type": 9, "optional": false } ], @@ -4439,7 +6057,7 @@ }, { "name": "type", - "type": 14, + "type": 11, "optional": false } ], @@ -4449,6 +6067,55 @@ "kind": "literal", "value": "text" }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 13, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "object", "properties": [ @@ -4469,7 +6136,7 @@ }, { "name": "type", - "type": 16, + "type": 18, "optional": false } ], @@ -4484,7 +6151,7 @@ "properties": [ { "name": "attachment", - "type": 18, + "type": 20, "optional": false }, { @@ -4494,7 +6161,7 @@ }, { "name": "type", - "type": 25, + "type": 27, "optional": false } ], @@ -4520,7 +6187,7 @@ }, { "name": "mediaType", - "type": 19, + "type": 21, "optional": false }, { @@ -4530,7 +6197,7 @@ }, { "name": "originalDimensions", - "type": 24, + "type": 26, "optional": true }, { @@ -4544,10 +6211,10 @@ { "kind": "union", "types": [ - 20, - 21, 22, - 23 + 23, + 24, + 25 ] }, { @@ -4591,12 +6258,12 @@ "properties": [ { "name": "attachment", - "type": 27, + "type": 29, "optional": false }, { "name": "type", - "type": 28, + "type": 30, "optional": false } ], @@ -4713,12 +6380,12 @@ }, { "name": "shadowedRange", - "type": 29, + "type": 31, "optional": false }, { "name": "shadowedSeqs", - "type": 30, + "type": 32, "optional": false }, { @@ -4738,7 +6405,7 @@ }, { "name": "usage", - "type": 31, + "type": 33, "optional": true } ], @@ -4851,6 +6518,2805 @@ ] } }, + { + "key": "event:developer/message", + "kind": "event", + "event": "developer/message", + "surface": true, + "digest": "eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 195, + "optional": true + }, + { + "name": "surfaceOp", + "type": 196, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 199, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "headerSeq", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 14, + 16, + 18, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 33, + 36, + 38, + 40, + 42, + 44, + 46, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 111, + 113, + 116, + 117, + 118, + 119, + 120, + 122, + 123, + 124, + 125, + 127, + 128, + 129, + 130, + 131, + 133, + 135, + 136, + 138, + 139, + 147, + 149, + 150, + 152, + 154, + 158, + 160, + 168, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 186, + 188, + 189, + 190, + 191, + 192, + 193, + 194 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 110, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 112, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 114, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 115, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 121, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 126, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 132, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 137, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 26, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 140, + "optional": false + }, + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 141 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 142, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 143, + 144, + 145 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 134, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 155, + "optional": false + }, + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 157, + "optional": false + }, + { + "name": "update", + "type": 26, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "references", + "type": 162, + "optional": false + }, + { + "name": "version", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 163 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 164, + "optional": false + }, + { + "name": "compacted", + "type": 166, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 166, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 165 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 171 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 185, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 187, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 197, + 198 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 2, + "optional": false + }, + { + "name": "op", + "type": 144, + "optional": false + }, + { + "name": "startSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer/message" + } + ] + } + }, { "key": "event:feedback/message-delete", "kind": "event", @@ -6393,7 +10859,7 @@ "kind": "event", "event": "request/header", "surface": false, - "digest": "8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489", + "digest": "4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41", "schema": { "root": 0, "nodes": [ @@ -6422,7 +10888,7 @@ }, { "name": "type", - "type": 18, + "type": 19, "optional": false } ], @@ -6438,7 +10904,7 @@ }, { "name": "reason", - "type": 13, + "type": 14, "optional": false }, { @@ -6463,9 +10929,14 @@ "optional": false }, { - "name": "tools", + "name": "system", "type": 9, "optional": true + }, + { + "name": "tools", + "type": 10, + "optional": true } ], "indices": [] @@ -6538,13 +11009,22 @@ "kind": "array", "element": 7 }, + { + "kind": "primitive", + "type": "never" + }, { "kind": "array", - "element": 10 + "element": 11 }, { "kind": "object", "properties": [ + { + "name": "deferLoading", + "type": 4, + "optional": true + }, { "name": "description", "type": 7, @@ -6557,7 +11037,7 @@ }, { "name": "parameters", - "type": 11, + "type": 12, "optional": false } ], @@ -6569,7 +11049,7 @@ "indices": [ { "key": 7, - "value": 12 + "value": 13 } ] }, @@ -6580,10 +11060,10 @@ { "kind": "union", "types": [ - 14, 15, 16, - 17 + 17, + 18 ] }, { @@ -7299,7 +11779,7 @@ "kind": "event", "event": "session/title-llm-request", "surface": false, - "digest": "e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d", + "digest": "fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d", "schema": { "root": 0, "nodes": [ @@ -7313,7 +11793,7 @@ }, { "name": "ignorable", - "type": 19, + "type": 29, "optional": true }, { @@ -7328,7 +11808,7 @@ }, { "name": "type", - "type": 91, + "type": 205, "optional": false } ], @@ -7354,17 +11834,17 @@ }, { "name": "route", - "type": 90, + "type": 204, "optional": false }, { "name": "system", - "type": 9, + "type": 10, "optional": false }, { "name": "titleProvider", - "type": 9, + "type": 10, "optional": false } ], @@ -7382,27 +11862,47 @@ "kind": "array", "element": 5 }, + { + "kind": "union", + "types": [ + 6, + 37, + 199, + 200, + 202 + ] + }, { "kind": "object", "properties": [ { "name": "content", - "type": 6, + "type": 7, "optional": false }, { "name": "id", - "type": 9, + "type": 10, "optional": false }, + { + "name": "isError", + "type": 34, + "optional": true + }, { "name": "role", - "type": 31, + "type": 35, "optional": false }, { "name": "source", - "type": 35, + "type": 36, + "optional": false + }, + { + "name": "toolCallId", + "type": 10, "optional": false } ], @@ -7410,40 +11910,31 @@ }, { "kind": "array", - "element": 7 + "element": 8 }, { "kind": "union", "types": [ - 8, - 11, + 9, + 12, + 14, + 17, + 19, 21, - 24, - 27, - 29 + 31 ] }, { "kind": "object", "properties": [ { - "name": "arguments", - "type": 9, - "optional": false - }, - { - "name": "id", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 9, + "name": "text", + "type": 10, "optional": false }, { "name": "type", - "type": 10, + "type": 11, "optional": false } ], @@ -7455,21 +11946,95 @@ }, { "kind": "literal", - "value": "tool-call" + "value": "reasoning" }, { "kind": "object", "properties": [ { - "name": "attachment", - "type": 12, + "name": "text", + "type": 10, "optional": false }, { - "name": "offloaded", - "type": 19, + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 15, "optional": true }, + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 10, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + }, { "name": "type", "type": 20, @@ -7478,12 +12043,37 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 22, + "optional": false + }, + { + "name": "offloaded", + "type": 29, + "optional": true + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, { "kind": "object", "properties": [ { "name": "attachmentId", - "type": 9, + "type": 10, "optional": false }, { @@ -7498,17 +12088,17 @@ }, { "name": "mediaType", - "type": 13, + "type": 23, "optional": false }, { "name": "name", - "type": 9, + "type": 10, "optional": true }, { "name": "originalDimensions", - "type": 18, + "type": 28, "optional": true }, { @@ -7522,10 +12112,10 @@ { "kind": "union", "types": [ - 14, - 15, - 16, - 17 + 24, + 25, + 26, + 27 ] }, { @@ -7573,12 +12163,12 @@ "properties": [ { "name": "attachment", - "type": 22, + "type": 32, "optional": false }, { "name": "type", - "type": 23, + "type": 33, "optional": false } ], @@ -7589,7 +12179,7 @@ "properties": [ { "name": "attachmentId", - "type": 9, + "type": 10, "optional": false }, { @@ -7599,7 +12189,7 @@ }, { "name": "name", - "type": 9, + "type": 10, "optional": false } ], @@ -7609,148 +12199,216 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 6, - "optional": false - }, - { - "name": "isError", - "type": 25, - "optional": true - }, - { - "name": "toolCallId", - "type": 9, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, { "kind": "primitive", "type": "boolean" }, { "kind": "literal", - "value": "tool-result" + "value": "tool" }, { "kind": "object", "properties": [ { - "name": "text", - "type": 9, + "name": "callId", + "type": 10, "optional": false }, { - "name": "type", - "type": 28, + "name": "kind", + "type": 35, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "reasoning" - }, { "kind": "object", "properties": [ { - "name": "text", - "type": 9, + "name": "content", + "type": 7, "optional": false }, { - "name": "type", - "type": 30, + "name": "id", + "type": 10, "optional": false + }, + { + "name": "role", + "type": 38, + "optional": false + }, + { + "name": "source", + "type": 39, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } } ], "indices": [] }, { "kind": "literal", - "value": "text" - }, - { - "kind": "union", - "types": [ - 32, - 33, - 34 - ] - }, - { - "kind": "literal", - "value": "system" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "literal", - "value": "user" + "value": "developer" }, { "kind": "union", "types": [ 36, + 40, + 43, 45, 47, - 48, + 49, 51, - 56, - 58, - 63, - 64, - 65, - 67, - 69, + 53, + 55, + 57, + 59, + 61, 70, - 77, - 79, - 81, - 83, + 72, + 74, + 76, + 78, + 80, 85, - 88, - 89 + 87, + 95, + 100, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 142, + 143, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 174, + 175, + 177, + 180, + 181, + 182, + 183, + 184, + 186, + 187, + 188, + 189, + 190, + 192, + 193, + 194, + 195, + 196, + 198 ] }, { "kind": "object", "properties": [ - { - "name": "baseline", - "type": 19, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 9, - "optional": true - }, - { - "name": "changes", - "type": 37, - "optional": false - }, { "name": "form", - "type": 43, + "type": 41, "optional": false }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ { "name": "kind", "type": 44, @@ -7759,31 +12417,246 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 29, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 10, + "optional": true + }, + { + "name": "changes", + "type": 62, + "optional": false + }, + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 69, + "optional": false + } + ], + "indices": [] + }, { "kind": "array", - "element": 38 + "element": 63 }, { "kind": "object", "properties": [ { "name": "action", - "type": 39, + "type": 64, "optional": false }, { "name": "digest", - "type": 9, + "type": 10, "optional": true }, { "name": "path", - "type": 9, + "type": 10, "optional": false }, { "name": "scope", - "type": 9, + "type": 10, "optional": false } ], @@ -7792,9 +12665,9 @@ { "kind": "union", "types": [ - 40, - 41, - 42 + 65, + 66, + 67 ] }, { @@ -7821,13 +12694,18 @@ "kind": "object", "properties": [ { - "name": "callId", - "type": 9, - "optional": false + "name": "clientTimeZone", + "type": 10, + "optional": true }, { "name": "kind", - "type": 46, + "type": 71, + "optional": false + }, + { + "name": "rpcId", + "type": 10, "optional": false } ], @@ -7835,74 +12713,99 @@ }, { "kind": "literal", - "value": "tool" + "value": "user" }, { "kind": "object", "properties": [ { - "name": "clientTimeZone", - "type": 9, - "optional": true - }, - { - "name": "kind", - "type": 34, + "name": "compactionId", + "type": 10, "optional": false }, { - "name": "rpcId", - "type": 9, + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "summary", + "type": 10, "optional": false } ], "indices": [] }, + { + "kind": "literal", + "value": "tool-goal" + }, { "kind": "object", "properties": [ { "name": "deliveryId", - "type": 9, + "type": 10, "optional": false }, { "name": "form", - "type": 49, + "type": 41, "optional": false }, { "name": "kind", - "type": 50, + "type": 77, "optional": false }, { "name": "provider", - "type": 9, + "type": 10, "optional": false }, { "name": "ruleId", - "type": 9, + "type": 10, "optional": false }, { "name": "source", - "type": 9, + "type": 10, "optional": false }, { "name": "summary", - "type": 9, + "type": 10, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "notice" - }, { "kind": "literal", "value": "webhook" @@ -7910,24 +12813,49 @@ { "kind": "object", "properties": [ - { - "name": "entries", - "type": 52, - "optional": false - }, { "name": "form", - "type": 54, + "type": 41, "optional": false }, { "name": "kind", - "type": 55, + "type": 79, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 81, + "optional": false + }, + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 84, "optional": false }, { "name": "update", - "type": 19, + "type": 29, "optional": true } ], @@ -7935,19 +12863,19 @@ }, { "kind": "array", - "element": 53 + "element": 82 }, { "kind": "object", "properties": [ { "name": "description", - "type": 9, + "type": 10, "optional": false }, { "name": "name", - "type": 9, + "type": 10, "optional": false } ], @@ -7966,17 +12894,17 @@ "properties": [ { "name": "form", - "type": 43, + "type": 68, "optional": false }, { "name": "kind", - "type": 57, + "type": 86, "optional": false }, { "name": "name", - "type": 9, + "type": 10, "optional": false } ], @@ -7991,118 +12919,22 @@ "properties": [ { "name": "form", - "type": 59, + "type": 88, "optional": false }, { "name": "kind", - "type": 60, + "type": 89, "optional": false }, { - "name": "plugin", - "type": 9, + "name": "references", + "type": 90, "optional": false }, { - "name": "sections", - "type": 61, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 62 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 9, - "optional": false - }, - { - "name": "text", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - }, - { - "name": "summary", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 66, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, + "name": "version", + "type": 94, "optional": false } ], @@ -8112,85 +12944,13 @@ "kind": "literal", "value": "recall" }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 68, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 54, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 66, - "optional": false - }, - { - "name": "kind", - "type": 71, - "optional": false - }, - { - "name": "references", - "type": 72, - "optional": false - }, - { - "name": "version", - "type": 76, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", "value": "session-reference" }, { "kind": "array", - "element": 73 + "element": 91 }, { "kind": "object", @@ -8202,12 +12962,12 @@ }, { "name": "capturedThroughSeq", - "type": 74, + "type": 92, "optional": false }, { "name": "compacted", - "type": 25, + "type": 34, "optional": false }, { @@ -8217,7 +12977,7 @@ }, { "name": "label", - "type": 9, + "type": 10, "optional": false }, { @@ -8242,12 +13002,12 @@ }, { "name": "sessionId", - "type": 9, + "type": 10, "optional": false }, { "name": "truncated", - "type": 25, + "type": 34, "optional": false } ], @@ -8257,7 +13017,7 @@ "kind": "union", "types": [ 2, - 75 + 93 ] }, { @@ -8273,22 +13033,769 @@ "properties": [ { "name": "form", - "type": 49, + "type": 96, "optional": false }, { "name": "kind", - "type": 78, + "type": 97, "optional": false }, { - "name": "senderSessionId", - "type": 9, + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "array", + "element": 99 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 44, "optional": false }, { "name": "summary", - "type": 9, + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 141, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, "optional": false } ], @@ -8303,17 +13810,309 @@ "properties": [ { "name": "form", - "type": 68, + "type": 88, "optional": false }, { "name": "kind", - "type": 80, + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 162, "optional": false }, { "name": "senderSessionId", - "type": 9, + "type": 10, "optional": false } ], @@ -8327,13 +14126,157 @@ "kind": "object", "properties": [ { - "name": "goalId", - "type": 9, + "name": "form", + "type": 83, "optional": false }, { "name": "kind", - "type": 82, + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 173, "optional": false }, { @@ -8356,29 +14299,50 @@ { "kind": "object", "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, { "name": "kind", - "type": 84, + "type": 97, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 176, "optional": false }, { "name": "messageId", - "type": 9, + "type": 10, "optional": false }, { "name": "senderId", - "type": 9, + "type": 10, "optional": false }, { "name": "senderName", - "type": 9, + "type": 10, "optional": false }, { "name": "teamId", - "type": 9, + "type": 10, "optional": false } ], @@ -8393,22 +14357,22 @@ "properties": [ { "name": "kind", - "type": 86, + "type": 178, "optional": false }, { "name": "model", - "type": 9, + "type": 10, "optional": false }, { "name": "provider", - "type": 9, + "type": 10, "optional": false }, { "name": "replayState", - "type": 87, + "type": 179, "optional": true } ], @@ -8427,12 +14391,7 @@ "properties": [ { "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, + "type": 97, "optional": false } ], @@ -8443,23 +14402,295 @@ "properties": [ { "name": "kind", - "type": 34, + "type": 101, "optional": false } ], "indices": [] }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 185, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 191, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 197, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 71, + "optional": false + }, + { + "name": "source", + "type": 39, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 201, + "optional": false + }, + { + "name": "source", + "type": 177, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 203, + "optional": false + }, + { + "name": "source", + "type": 190, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system" + }, { "kind": "object", "properties": [ { "name": "model", - "type": 9, + "type": 10, "optional": false }, { "name": "provider", - "type": 9, + "type": 10, "optional": false } ], @@ -9020,7 +15251,7 @@ "kind": "event", "event": "system/message", "surface": true, - "digest": "69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae", + "digest": "69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1", "schema": { "root": 0, "nodes": [ @@ -9044,12 +15275,12 @@ }, { "name": "sourceEventSeqs", - "type": 47, + "type": 34, "optional": true }, { "name": "surfaceOp", - "type": 48, + "type": 35, "optional": false }, { @@ -9059,7 +15290,7 @@ }, { "name": "type", - "type": 52, + "type": 39, "optional": false } ], @@ -9101,12 +15332,12 @@ }, { "name": "role", - "type": 29, + "type": 31, "optional": false }, { "name": "source", - "type": 30, + "type": 32, "optional": false } ], @@ -9123,8 +15354,9 @@ 8, 19, 22, - 25, - 27 + 24, + 26, + 29 ] }, { @@ -9321,35 +15553,21 @@ "kind": "object", "properties": [ { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 23, - "optional": true - }, - { - "name": "toolCallId", + "name": "text", "type": 6, "optional": false }, { "name": "type", - "type": 24, + "type": 23, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "boolean" - }, { "kind": "literal", - "value": "tool-result" + "value": "text" }, { "kind": "object", @@ -9361,7 +15579,7 @@ }, { "name": "type", - "type": 26, + "type": 25, "optional": false } ], @@ -9375,7 +15593,12 @@ "kind": "object", "properties": [ { - "name": "text", + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", "type": 6, "optional": false }, @@ -9387,225 +15610,52 @@ ], "indices": [] }, + { + "kind": "primitive", + "type": "never" + }, { "kind": "literal", - "value": "text" + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" }, { "kind": "literal", "value": "system" }, - { - "kind": "union", - "types": [ - 31, - 36, - 38, - 40, - 42, - 44, - 46 - ] - }, { "kind": "object", "properties": [ - { - "name": "form", - "type": 32, - "optional": false - }, { "name": "kind", "type": 33, "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - }, - { - "name": "sections", - "type": 34, - "optional": false } ], "indices": [] }, { "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 35 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - }, - { - "name": "summary", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 41, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] + "value": "system-prompt" }, { "kind": "array", @@ -9614,8 +15664,8 @@ { "kind": "union", "types": [ - 49, - 51 + 36, + 38 ] }, { @@ -9628,7 +15678,7 @@ }, { "name": "op", - "type": 50, + "type": 37, "optional": false }, { @@ -9908,7 +15958,7 @@ "kind": "event", "event": "team/message/queued", "surface": false, - "digest": "443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4", + "digest": "21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d", "schema": { "root": 0, "nodes": [ @@ -9922,22 +15972,22 @@ }, { "name": "ignorable", - "type": 24, + "type": 26, "optional": true }, { "name": "seq", - "type": 17, + "type": 19, "optional": false }, { "name": "time", - "type": 17, + "type": 19, "optional": false }, { "name": "type", - "type": 30, + "type": 32, "optional": false } ], @@ -9953,12 +16003,12 @@ }, { "name": "teamId", - "type": 7, + "type": 6, "optional": false }, { "name": "version", - "type": 29, + "type": 31, "optional": false } ], @@ -9974,22 +16024,22 @@ }, { "name": "id", - "type": 7, + "type": 6, "optional": false }, { "name": "senderId", - "type": 7, + "type": 6, "optional": false }, { "name": "senderName", - "type": 7, + "type": 6, "optional": false }, { "name": "targetId", - "type": 7, + "type": 6, "optional": false } ], @@ -10003,67 +16053,34 @@ "kind": "union", "types": [ 5, - 9, - 11, + 8, + 10, 13, 15, - 26 + 17, + 28 ] }, { "kind": "object", "properties": [ { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", + "name": "text", "type": 6, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, "optional": false }, { "name": "type", - "type": 8, + "type": 7, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "boolean" - }, { "kind": "primitive", "type": "string" }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", "value": "reasoning" @@ -10073,12 +16090,12 @@ "properties": [ { "name": "text", - "type": 7, + "type": 6, "optional": false }, { "name": "type", - "type": 12, + "type": 9, "optional": false } ], @@ -10092,18 +16109,37 @@ "kind": "object", "properties": [ { - "name": "arguments", - "type": 7, + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, "optional": false }, { - "name": "id", - "type": 7, + "name": "type", + "type": 12, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ { - "name": "name", - "type": 7, + "name": "toolName", + "type": 6, "optional": false }, { @@ -10114,6 +16150,36 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "tool-call" @@ -10123,17 +16189,17 @@ "properties": [ { "name": "attachment", - "type": 16, + "type": 18, "optional": false }, { "name": "offloaded", - "type": 24, + "type": 26, "optional": true }, { "name": "type", - "type": 25, + "type": 27, "optional": false } ], @@ -10144,37 +16210,37 @@ "properties": [ { "name": "attachmentId", - "type": 7, + "type": 6, "optional": false }, { "name": "bytes", - "type": 17, + "type": 19, "optional": false }, { "name": "height", - "type": 17, + "type": 19, "optional": false }, { "name": "mediaType", - "type": 18, + "type": 20, "optional": false }, { "name": "name", - "type": 7, + "type": 6, "optional": true }, { "name": "originalDimensions", - "type": 23, + "type": 25, "optional": true }, { "name": "width", - "type": 17, + "type": 19, "optional": false } ], @@ -10187,10 +16253,10 @@ { "kind": "union", "types": [ - 19, - 20, 21, - 22 + 22, + 23, + 24 ] }, { @@ -10214,12 +16280,12 @@ "properties": [ { "name": "height", - "type": 17, + "type": 19, "optional": false }, { "name": "width", - "type": 17, + "type": 19, "optional": false } ], @@ -10238,12 +16304,12 @@ "properties": [ { "name": "attachment", - "type": 27, + "type": 29, "optional": false }, { "name": "type", - "type": 28, + "type": 30, "optional": false } ], @@ -10254,17 +16320,17 @@ "properties": [ { "name": "attachmentId", - "type": 7, + "type": 6, "optional": false }, { "name": "bytes", - "type": 17, + "type": 19, "optional": false }, { "name": "name", - "type": 7, + "type": 6, "optional": false } ], @@ -11009,7 +17075,7 @@ "kind": "event", "event": "tool/ptc-dispatch", "surface": false, - "digest": "b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c", + "digest": "100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163", "schema": { "root": 0, "nodes": [ @@ -11023,22 +17089,22 @@ }, { "name": "ignorable", - "type": 24, + "type": 26, "optional": true }, { "name": "seq", - "type": 17, + "type": 19, "optional": false }, { "name": "time", - "type": 17, + "type": 19, "optional": false }, { "name": "type", - "type": 30, + "type": 33, "optional": false } ], @@ -11059,32 +17125,32 @@ }, { "name": "error", - "type": 29, + "type": 31, "optional": true }, { "name": "isError", - "type": 6, + "type": 32, "optional": false }, { "name": "name", - "type": 7, + "type": 6, "optional": false }, { "name": "parentCallId", - "type": 7, + "type": 6, "optional": false }, { "name": "rootCallId", - "type": 7, + "type": 6, "optional": false }, { "name": "subCallId", - "type": 7, + "type": 6, "optional": false } ], @@ -11102,67 +17168,34 @@ "kind": "union", "types": [ 5, - 9, - 11, + 8, + 10, 13, 15, - 26 + 17, + 28 ] }, { "kind": "object", "properties": [ { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", + "name": "text", "type": 6, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, "optional": false }, { "name": "type", - "type": 8, + "type": 7, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "boolean" - }, { "kind": "primitive", "type": "string" }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", "value": "reasoning" @@ -11172,12 +17205,12 @@ "properties": [ { "name": "text", - "type": 7, + "type": 6, "optional": false }, { "name": "type", - "type": 12, + "type": 9, "optional": false } ], @@ -11191,18 +17224,37 @@ "kind": "object", "properties": [ { - "name": "arguments", - "type": 7, + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, "optional": false }, { - "name": "id", - "type": 7, + "name": "type", + "type": 12, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ { - "name": "name", - "type": 7, + "name": "toolName", + "type": 6, "optional": false }, { @@ -11213,6 +17265,36 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "tool-call" @@ -11222,17 +17304,17 @@ "properties": [ { "name": "attachment", - "type": 16, + "type": 18, "optional": false }, { "name": "offloaded", - "type": 24, + "type": 26, "optional": true }, { "name": "type", - "type": 25, + "type": 27, "optional": false } ], @@ -11243,37 +17325,37 @@ "properties": [ { "name": "attachmentId", - "type": 7, + "type": 6, "optional": false }, { "name": "bytes", - "type": 17, + "type": 19, "optional": false }, { "name": "height", - "type": 17, + "type": 19, "optional": false }, { "name": "mediaType", - "type": 18, + "type": 20, "optional": false }, { "name": "name", - "type": 7, + "type": 6, "optional": true }, { "name": "originalDimensions", - "type": 23, + "type": 25, "optional": true }, { "name": "width", - "type": 17, + "type": 19, "optional": false } ], @@ -11286,10 +17368,10 @@ { "kind": "union", "types": [ - 19, - 20, 21, - 22 + 22, + 23, + 24 ] }, { @@ -11313,12 +17395,12 @@ "properties": [ { "name": "height", - "type": 17, + "type": 19, "optional": false }, { "name": "width", - "type": 17, + "type": 19, "optional": false } ], @@ -11337,12 +17419,12 @@ "properties": [ { "name": "attachment", - "type": 27, + "type": 29, "optional": false }, { "name": "type", - "type": 28, + "type": 30, "optional": false } ], @@ -11353,17 +17435,17 @@ "properties": [ { "name": "attachmentId", - "type": 7, + "type": 6, "optional": false }, { "name": "bytes", - "type": 17, + "type": 19, "optional": false }, { "name": "name", - "type": 7, + "type": 6, "optional": false } ], @@ -11378,22 +17460,26 @@ "properties": [ { "name": "code", - "type": 7, + "type": 6, "optional": false }, { "name": "name", - "type": 7, + "type": 6, "optional": false }, { "name": "reason", - "type": 7, + "type": 6, "optional": true } ], "indices": [] }, + { + "kind": "primitive", + "type": "boolean" + }, { "kind": "literal", "value": "tool/ptc-dispatch" @@ -11500,7 +17586,7 @@ "kind": "event", "event": "tool/result", "surface": true, - "digest": "29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2", + "digest": "7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397", "schema": { "root": 0, "nodes": [ @@ -11514,32 +17600,32 @@ }, { "name": "ignorable", - "type": 24, + "type": 27, "optional": true }, { "name": "seq", - "type": 17, + "type": 20, "optional": false }, { "name": "sourceEventSeqs", - "type": 38, + "type": 39, "optional": true }, { "name": "surfaceOp", - "type": 39, + "type": 40, "optional": false }, { "name": "time", - "type": 17, + "type": 20, "optional": false }, { "name": "type", - "type": 43, + "type": 44, "optional": false } ], @@ -11560,17 +17646,17 @@ }, { "name": "meta", - "type": 34, + "type": 35, "optional": true }, { "name": "step", - "type": 17, + "type": 20, "optional": false }, { "name": "turn", - "type": 17, + "type": 20, "optional": false } ], @@ -11614,68 +17700,43 @@ "type": 3, "optional": false }, + { + "name": "isError", + "type": 32, + "optional": true + }, { "name": "role", - "type": 31, + "type": 33, "optional": false }, { "name": "source", - "type": 32, + "type": 34, "optional": false - } - ], - "indices": [] - }, - { - "kind": "tuple", - "elements": [ - { - "type": 6, - "optional": false, - "rest": false - } - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 7, - "optional": false - }, - { - "name": "isError", - "type": 29, - "optional": true }, { "name": "toolCallId", "type": 3, "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false } ], "indices": [] }, { "kind": "array", - "element": 8 + "element": 6 }, { "kind": "union", "types": [ - 6, + 7, 9, 11, - 13, - 15, - 26 + 14, + 16, + 18, + 29 ] }, { @@ -11688,7 +17749,7 @@ }, { "name": "type", - "type": 10, + "type": 8, "optional": false } ], @@ -11708,7 +17769,7 @@ }, { "name": "type", - "type": 12, + "type": 10, "optional": false } ], @@ -11718,6 +17779,55 @@ "kind": "literal", "value": "reasoning" }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "object", "properties": [ @@ -11738,7 +17848,7 @@ }, { "name": "type", - "type": 14, + "type": 17, "optional": false } ], @@ -11753,17 +17863,17 @@ "properties": [ { "name": "attachment", - "type": 16, + "type": 19, "optional": false }, { "name": "offloaded", - "type": 24, + "type": 27, "optional": true }, { "name": "type", - "type": 25, + "type": 28, "optional": false } ], @@ -11779,17 +17889,17 @@ }, { "name": "bytes", - "type": 17, + "type": 20, "optional": false }, { "name": "height", - "type": 17, + "type": 20, "optional": false }, { "name": "mediaType", - "type": 18, + "type": 21, "optional": false }, { @@ -11799,12 +17909,12 @@ }, { "name": "originalDimensions", - "type": 23, + "type": 26, "optional": true }, { "name": "width", - "type": 17, + "type": 20, "optional": false } ], @@ -11817,10 +17927,10 @@ { "kind": "union", "types": [ - 19, - 20, - 21, - 22 + 22, + 23, + 24, + 25 ] }, { @@ -11844,12 +17954,12 @@ "properties": [ { "name": "height", - "type": 17, + "type": 20, "optional": false }, { "name": "width", - "type": 17, + "type": 20, "optional": false } ], @@ -11868,12 +17978,12 @@ "properties": [ { "name": "attachment", - "type": 27, + "type": 30, "optional": false }, { "name": "type", - "type": 28, + "type": 31, "optional": false } ], @@ -11889,7 +17999,7 @@ }, { "name": "bytes", - "type": 17, + "type": 20, "optional": false }, { @@ -11910,11 +18020,7 @@ }, { "kind": "literal", - "value": "tool-result" - }, - { - "kind": "literal", - "value": "user" + "value": "tool" }, { "kind": "object", @@ -11932,24 +18038,20 @@ ], "indices": [] }, - { - "kind": "literal", - "value": "tool" - }, { "kind": "union", "types": [ 3, - 17, - 29, - 35, + 20, + 32, 36, - 37 + 37, + 38 ] }, { "kind": "array", - "element": 34 + "element": 35 }, { "kind": "primitive", @@ -11961,19 +18063,19 @@ "indices": [ { "key": 3, - "value": 34 + "value": 35 } ] }, { "kind": "array", - "element": 17 + "element": 20 }, { "kind": "union", "types": [ - 40, - 41 + 41, + 42 ] }, { @@ -11985,17 +18087,17 @@ "properties": [ { "name": "endSeq", - "type": 17, + "type": 20, "optional": false }, { "name": "op", - "type": 42, + "type": 43, "optional": false }, { "name": "startSeq", - "type": 17, + "type": 20, "optional": false } ], @@ -12017,7 +18119,7 @@ "kind": "event", "event": "turn/end", "surface": false, - "digest": "bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b", + "digest": "0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce", "schema": { "root": 0, "nodes": [ @@ -12031,22 +18133,22 @@ }, { "name": "ignorable", - "type": 29, + "type": 31, "optional": true }, { "name": "seq", - "type": 14, + "type": 16, "optional": false }, { "name": "time", - "type": 14, + "type": 16, "optional": false }, { "name": "type", - "type": 30, + "type": 32, "optional": false } ], @@ -12062,7 +18164,7 @@ }, { "name": "turn", - "type": 14, + "type": 16, "optional": false } ], @@ -12076,7 +18178,8 @@ 7, 9, 11, - 16 + 13, + 18 ] }, { @@ -12122,7 +18225,7 @@ }, { "kind": "literal", - "value": "interrupted" + "value": "forked" }, { "kind": "object", @@ -12135,6 +18238,21 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "max-tokens" @@ -12144,12 +18262,12 @@ "properties": [ { "name": "error", - "type": 12, + "type": 14, "optional": false }, { "name": "kind", - "type": 15, + "type": 17, "optional": false } ], @@ -12160,32 +18278,32 @@ "properties": [ { "name": "code", - "type": 13, + "type": 15, "optional": false }, { "name": "message", - "type": 13, + "type": 15, "optional": false }, { "name": "offloadImages", - "type": 14, + "type": 16, "optional": true }, { "name": "providerRetryAfterMs", - "type": 14, + "type": 16, "optional": true }, { "name": "requestId", - "type": 13, + "type": 15, "optional": true }, { "name": "status", - "type": 14, + "type": 16, "optional": true } ], @@ -12208,12 +18326,12 @@ "properties": [ { "name": "kind", - "type": 17, + "type": 19, "optional": false }, { "name": "reason", - "type": 18, + "type": 20, "optional": false } ], @@ -12226,28 +18344,13 @@ { "kind": "union", "types": [ - 19, 21, 23, 25, - 27 + 27, + 29 ] }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "user" - }, { "kind": "object", "properties": [ @@ -12255,13 +18358,18 @@ "name": "kind", "type": 22, "optional": false + }, + { + "name": "reason", + "type": 15, + "optional": false } ], "indices": [] }, { "kind": "literal", - "value": "disposed" + "value": "hook" }, { "kind": "object", @@ -12276,7 +18384,7 @@ }, { "kind": "literal", - "value": "legacy" + "value": "parent" }, { "kind": "object", @@ -12291,7 +18399,7 @@ }, { "kind": "literal", - "value": "parent" + "value": "user" }, { "kind": "object", @@ -12300,10 +18408,20 @@ "name": "kind", "type": 28, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ { - "name": "reason", - "type": 13, + "name": "kind", + "type": 30, "optional": false } ], @@ -12311,7 +18429,7 @@ }, { "kind": "literal", - "value": "hook" + "value": "legacy" }, { "kind": "literal", @@ -12395,7 +18513,7 @@ "kind": "event", "event": "user/message", "surface": true, - "digest": "314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578", + "digest": "3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761", "schema": { "root": 0, "nodes": [ @@ -12409,32 +18527,32 @@ }, { "name": "ignorable", - "type": 16, + "type": 25, "optional": true }, { "name": "seq", - "type": 9, + "type": 18, "optional": false }, { "name": "sourceEventSeqs", - "type": 84, + "type": 193, "optional": true }, { "name": "surfaceOp", - "type": 85, + "type": 194, "optional": false }, { "name": "time", - "type": 9, + "type": 18, "optional": false }, { "name": "type", - "type": 88, + "type": 197, "optional": false } ], @@ -12455,13 +18573,23 @@ }, { "name": "role", - "type": 28, + "type": 30, "optional": false }, { "name": "source", - "type": 29, - "optional": false + "type": 31, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } } ], "indices": [] @@ -12475,12 +18603,106 @@ "types": [ 4, 7, - 18, - 21, - 24, - 26 + 9, + 12, + 14, + 16, + 27 ] }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "object", "properties": [ @@ -12501,16 +18723,12 @@ }, { "name": "type", - "type": 6, + "type": 15, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "string" - }, { "kind": "literal", "value": "tool-call" @@ -12520,17 +18738,17 @@ "properties": [ { "name": "attachment", - "type": 8, + "type": 17, "optional": false }, { "name": "offloaded", - "type": 16, + "type": 25, "optional": true }, { "name": "type", - "type": 17, + "type": 26, "optional": false } ], @@ -12546,17 +18764,17 @@ }, { "name": "bytes", - "type": 9, + "type": 18, "optional": false }, { "name": "height", - "type": 9, + "type": 18, "optional": false }, { "name": "mediaType", - "type": 10, + "type": 19, "optional": false }, { @@ -12566,12 +18784,12 @@ }, { "name": "originalDimensions", - "type": 15, + "type": 24, "optional": true }, { "name": "width", - "type": 9, + "type": 18, "optional": false } ], @@ -12584,20 +18802,12 @@ { "kind": "union", "types": [ - 11, - 12, - 13, - 14 + 20, + 21, + 22, + 23 ] }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, { "kind": "literal", "value": "image/gif" @@ -12606,17 +18816,25 @@ "kind": "literal", "value": "image/jpeg" }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, { "kind": "object", "properties": [ { "name": "height", - "type": 9, + "type": 18, "optional": false }, { "name": "width", - "type": 9, + "type": 18, "optional": false } ], @@ -12635,12 +18853,12 @@ "properties": [ { "name": "attachment", - "type": 19, + "type": 28, "optional": false }, { "name": "type", - "type": 20, + "type": 29, "optional": false } ], @@ -12656,7 +18874,7 @@ }, { "name": "bytes", - "type": 9, + "type": 18, "optional": false }, { @@ -12671,80 +18889,6 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 22, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, { "kind": "literal", "value": "user" @@ -12752,189 +18896,128 @@ { "kind": "union", "types": [ - 30, + 32, + 35, + 37, 39, 41, - 42, - 45, + 43, + 46, + 48, 50, 52, - 57, + 54, + 56, 58, - 59, + 60, 61, + 62, 63, 64, + 65, + 67, + 68, + 69, + 70, 71, + 72, 73, + 74, 75, + 76, 77, + 78, 79, + 81, 82, - 83 + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 109, + 111, + 114, + 115, + 116, + 117, + 118, + 120, + 121, + 122, + 123, + 125, + 126, + 127, + 128, + 129, + 131, + 132, + 133, + 135, + 136, + 144, + 146, + 147, + 149, + 151, + 155, + 157, + 165, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 183, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192 ] }, { "kind": "object", "properties": [ - { - "name": "baseline", - "type": 16, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 5, - "optional": true - }, - { - "name": "changes", - "type": 31, - "optional": false - }, { "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 38, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 32 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", "type": 33, "optional": false }, - { - "name": "digest", - "type": 5, - "optional": true - }, - { - "name": "path", - "type": 5, - "optional": false - }, - { - "name": "scope", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 34, - 35, - 36 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 5, - "optional": false - }, { "name": "kind", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 5, - "optional": true - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "rpcId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 5, - "optional": false - }, - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 44, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "ruleId", - "type": 5, - "optional": false - }, - { - "name": "source", - "type": 5, + "type": 34, "optional": false }, { @@ -12951,157 +19034,19 @@ }, { "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 46, - "optional": false - }, - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 49, - "optional": false - }, - { - "name": "update", - "type": 16, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 47 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" + "value": "tmux-context" }, { "kind": "object", "properties": [ { "name": "form", - "type": 37, + "type": 33, "optional": false }, { "name": "kind", - "type": 51, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 53, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "sections", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 56 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "text", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, + "type": 36, "optional": false }, { @@ -13112,43 +19057,340 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "tool-goal" + }, { "kind": "object", "properties": [ { "name": "form", - "type": 37, + "type": 33, "optional": false }, { "name": "kind", - "type": 54, + "type": 38, "optional": false }, { - "name": "plugin", + "name": "summary", "type": 5, "optional": false } ], "indices": [] }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, { "kind": "object", "properties": [ { "name": "form", - "type": 60, + "type": 44, "optional": false }, { "name": "kind", - "type": 54, + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, "optional": false }, { - "name": "plugin", - "type": 5, + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 45, "optional": false } ], @@ -13163,17 +19405,204 @@ "properties": [ { "name": "form", - "type": 62, + "type": 66, "optional": false }, { "name": "kind", - "type": 54, + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, "optional": false }, { - "name": "plugin", - "type": 5, + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 45, "optional": false } ], @@ -13188,17 +19617,12 @@ "properties": [ { "name": "form", - "type": 48, + "type": 80, "optional": false }, { "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, + "type": 47, "optional": false } ], @@ -13209,157 +19633,188 @@ "properties": [ { "name": "form", - "type": 60, + "type": 80, "optional": false }, { "name": "kind", - "type": 65, - "optional": false - }, - { - "name": "references", - "type": 66, - "optional": false - }, - { - "name": "version", - "type": 70, + "type": 49, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 67 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 9, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 68, - "optional": false - }, - { - "name": "compacted", - "type": 22, - "optional": false - }, - { - "name": "inputIndex", - "type": 9, - "optional": false - }, - { - "name": "label", - "type": 5, - "optional": false - }, - { - "name": "omittedBytes", - "type": 9, - "optional": false - }, - { - "name": "omittedMessages", - "type": 9, - "optional": false - }, - { - "name": "originalMessages", - "type": 9, - "optional": false - }, - { - "name": "retainedMessages", - "type": 9, - "optional": false - }, - { - "name": "sessionId", - "type": 5, - "optional": false - }, - { - "name": "truncated", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 9, - 69 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, { "kind": "object", "properties": [ { "name": "form", - "type": 43, + "type": 80, "optional": false }, { "name": "kind", - "type": 72, - "optional": false - }, - { - "name": "senderSessionId", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, + "type": 51, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "subagent-settled" - }, { "kind": "object", "properties": [ { "name": "form", - "type": 62, + "type": 80, "optional": false }, { "name": "kind", - "type": 74, + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, "optional": false }, { - "name": "senderSessionId", - "type": 5, + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 45, "optional": false } ], @@ -13367,7 +19822,199 @@ }, { "kind": "literal", - "value": "agent-message" + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] }, { "kind": "object", @@ -13379,17 +20026,17 @@ }, { "name": "kind", - "type": 76, + "type": 108, "optional": false }, { "name": "revision", - "type": 9, + "type": 18, "optional": false }, { "name": "round", - "type": 9, + "type": 18, "optional": false } ], @@ -13404,7 +20051,7 @@ "properties": [ { "name": "kind", - "type": 78, + "type": 110, "optional": false }, { @@ -13439,7 +20086,7 @@ "properties": [ { "name": "kind", - "type": 80, + "type": 112, "optional": false }, { @@ -13454,7 +20101,7 @@ }, { "name": "replayState", - "type": 81, + "type": 113, "optional": true } ], @@ -13473,12 +20120,7 @@ "properties": [ { "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, + "type": 45, "optional": false } ], @@ -13489,7 +20131,230 @@ "properties": [ { "name": "kind", - "type": 28, + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 119, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 124, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 130, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 25, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 137, + "optional": false + }, + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 143, "optional": false } ], @@ -13497,13 +20362,887 @@ }, { "kind": "array", - "element": 9 + "element": 138 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 139, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] }, { "kind": "union", "types": [ - 86, - 87 + 140, + 141, + 142 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 145, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 152, + "optional": false + }, + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 154, + "optional": false + }, + { + "name": "update", + "type": 25, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 153 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 156, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 158, + "optional": false + }, + { + "name": "references", + "type": 159, + "optional": false + }, + { + "name": "version", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 160 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 18, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 161, + "optional": false + }, + { + "name": "compacted", + "type": 163, + "optional": false + }, + { + "name": "inputIndex", + "type": 18, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 18, + "optional": false + }, + { + "name": "omittedMessages", + "type": 18, + "optional": false + }, + { + "name": "originalMessages", + "type": 18, + "optional": false + }, + { + "name": "retainedMessages", + "type": 18, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 162 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 168 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 182, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 184, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 18 + }, + { + "kind": "union", + "types": [ + 195, + 196 ] }, { @@ -13515,17 +21254,17 @@ "properties": [ { "name": "endSeq", - "type": 9, + "type": 18, "optional": false }, { "name": "op", - "type": 35, + "type": 141, "optional": false }, { "name": "startSeq", - "type": 9, + "type": 18, "optional": false } ], @@ -13825,6 +21564,65 @@ "names": [], "sources": [] }, + { + "digest": "0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "022623b9ef98ec47ec3c3bae0c51027c70d2601141c5e92e26a0d83d1b4cef06", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "user-approval" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4", "schema": { @@ -13847,11 +21645,36 @@ } ] }, - "names": [ - "event:turn/end.data.reason[2]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:205" + "packages/core/session/src/types.ts:206" + ] + }, + { + "digest": "02b2c23f2d94b028c9588a8faace3fce1217405db346da3389368b495457bf79", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + } + ] + }, + "names": [], + "sources": [ + "packages/extensions/cordis-host-runner/src/index.ts:14" ] }, { @@ -13894,7 +21717,7 @@ "packages/interaction/user-approval/src/index.ts#ApprovalPolicy" ], "sources": [ - "packages/interaction/user-approval/src/index.ts:60" + "packages/interaction/user-approval/src/index.ts:67" ] }, { @@ -13912,694 +21735,7 @@ "packages/core/session/src/types.ts#SessionSeq" ], "sources": [ - "packages/core/session/src/types.ts:31" - ] - }, - { - "digest": "071d92b9dac661fcc826c678cf64d188f26fb93aab79c627b11a03acdd34dfca", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "union", - "types": [ - 1, - 5, - 31, - 34, - 36, - 38, - 55 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "argumentsDelta", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 2, - "optional": false - }, - { - "name": "index", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": true - }, - { - "name": "type", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "tool-call-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 6, - "optional": false - }, - { - "name": "index", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 7, - 9, - 19, - 22, - 26, - 28 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 10, - "optional": false - }, - { - "name": "offloaded", - "type": 17, - "optional": true - }, - { - "name": "type", - "type": 18, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 3, - "optional": false - }, - { - "name": "height", - "type": 3, - "optional": false - }, - { - "name": "mediaType", - "type": 11, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": true - }, - { - "name": "originalDimensions", - "type": 16, - "optional": true - }, - { - "name": "width", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 12, - 13, - 14, - 15 - ] - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 3, - "optional": false - }, - { - "name": "width", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 20, - "optional": false - }, - { - "name": "type", - "type": 21, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 23, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "block-end" - }, - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 32, - "optional": false - }, - { - "name": "index", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 33, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 8, - 18, - 21, - 25, - 27, - 29 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 3, - "optional": false - }, - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 35, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 3, - "optional": false - }, - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 37, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 39, - "optional": false - }, - { - "name": "replayState", - "type": 51, - "optional": true - }, - { - "name": "type", - "type": 54, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 40, - 43, - 45, - 47, - 49 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 41, - "optional": false - }, - { - "name": "kind", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 2, - "optional": false - }, - { - "name": "message", - "type": 2, - "optional": false - }, - { - "name": "offloadImages", - "type": 3, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 3, - "optional": true - }, - { - "name": "requestId", - "type": 2, - "optional": true - }, - { - "name": "status", - "type": 3, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 41, - "optional": false - }, - { - "name": "kind", - "type": 44, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 46, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 48, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "stop" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 50, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-calls" - }, - { - "kind": "object", - "properties": [ - { - "name": "blocks", - "type": 52, - "optional": true - }, - { - "name": "response", - "type": 53, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 53 - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "literal", - "value": "finish" - }, - { - "kind": "object", - "properties": [ - { - "name": "type", - "type": 56, - "optional": false - }, - { - "name": "usage", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "usage" - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 3, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 3, - "optional": true - }, - { - "name": "inputTokens", - "type": 3, - "optional": false - }, - { - "name": "outputTokens", - "type": 3, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 3, - "optional": true - }, - { - "name": "totalTokens", - "type": 3, - "optional": true - } - ], - "indices": [] - } - ] - }, - "names": [ - "packages/llm/llm/src/types.ts#StreamChunk" - ], - "sources": [ - "packages/llm/llm/src/types.ts:426" + "packages/core/session/src/types.ts:32" ] }, { @@ -14652,6 +21788,374 @@ "names": [], "sources": [] }, + { + "digest": "09655b34d7f3cf1e9005974de2357de2d4a60deea165d16dac1eadaa6ec539a8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "system-prompt" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 8, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 9, + "optional": true + }, + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#SystemMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts:151" + ] + }, { "digest": "0a30c3be336cdd4f8f34e66543a3d46d611c43986edd9b3ce6cbb9b721d3b5d3", "schema": { @@ -14773,11 +22277,9 @@ } ] }, - "names": [ - "event:turn/end.data.reason[1]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:203" + "packages/core/session/src/types.ts:204" ] }, { @@ -14819,9 +22321,7 @@ } ] }, - "names": [ - "event:request/header.data.header.tools[0].parameters" - ], + "names": [], "sources": [] }, { @@ -14859,7 +22359,7 @@ "packages/llm/llm/src/types.ts#ReplayEnvelope" ], "sources": [ - "packages/llm/llm/src/types.ts:404" + "packages/llm/llm/src/types.ts:418" ] }, { @@ -14955,9 +22455,7 @@ } ] }, - "names": [ - "event:team/message/delivered.data" - ], + "names": [], "sources": [ "packages/experimental/agent-team/src/types.ts:227" ] @@ -14976,355 +22474,6 @@ "names": [], "sources": [] }, - { - "digest": "0c3f4d2248d9bc9700e2d7253fa71aa9935f5c39af6f11de5727f08cccaf8383", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "message", - "type": 1, - "optional": false - }, - { - "name": "teamId", - "type": 6, - "optional": false - }, - { - "name": "version", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "senderId", - "type": 6, - "optional": false - }, - { - "name": "senderName", - "type": 6, - "optional": false - }, - { - "name": "targetId", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 4, - 8, - 10, - 12, - 14, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 5, - "optional": true - }, - { - "name": "toolCallId", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 15, - "optional": false - }, - { - "name": "offloaded", - "type": 23, - "optional": true - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 16, - "optional": false - }, - { - "name": "height", - "type": 16, - "optional": false - }, - { - "name": "mediaType", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "originalDimensions", - "type": 22, - "optional": true - }, - { - "name": "width", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 18, - 19, - 20, - 21 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 16, - "optional": false - }, - { - "name": "width", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 26, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "literal", - "value": 2 - } - ] - }, - "names": [ - "event:team/message/queued.data" - ], - "sources": [ - "packages/experimental/agent-team/src/types.ts:225" - ] - }, { "digest": "0c4205180f75b9ee1e0d878bd9a9851628b5dc18448486389d9c5fdc3f1ccda3", "schema": { @@ -15339,875 +22488,6 @@ "names": [], "sources": [] }, - { - "digest": "0c6412d3ba5e41adfaa6929c7d4093f2d52d8598c03f35844fc0d55e3070a3b1", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "step", - "type": 1, - "optional": false - }, - { - "name": "stream", - "type": 2, - "optional": false - }, - { - "name": "turn", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 4, - 9, - 67, - 69 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "args", - "type": 5, - "optional": false - }, - { - "name": "dt", - "type": 7, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "time0", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 1 - }, - { - "kind": "literal", - "value": "tool-call-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "chunk", - "type": 10, - "optional": false - }, - { - "name": "time", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 66, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 11, - 13, - 39, - 42, - 44, - 46, - 63 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "argumentsDelta", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 14, - "optional": false - }, - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 38, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 15, - 17, - 27, - 30, - 34, - 36 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 18, - "optional": false - }, - { - "name": "offloaded", - "type": 25, - "optional": true - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 1, - "optional": false - }, - { - "name": "height", - "type": 1, - "optional": false - }, - { - "name": "mediaType", - "type": 19, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "originalDimensions", - "type": 24, - "optional": true - }, - { - "name": "width", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 20, - 21, - 22, - 23 - ] - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 1, - "optional": false - }, - { - "name": "width", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 28, - "optional": false - }, - { - "name": "type", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 31, - "optional": false - }, - { - "name": "isError", - "type": 32, - "optional": true - }, - { - "name": "toolCallId", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 33, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 14 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 35, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 37, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "block-end" - }, - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 40, - "optional": false - }, - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 41, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 16, - 26, - 29, - 33, - 35, - 37 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 43, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 45, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 47, - "optional": false - }, - { - "name": "replayState", - "type": 59, - "optional": true - }, - { - "name": "type", - "type": 62, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 48, - 51, - 53, - 55, - 57 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 50, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 6, - "optional": false - }, - { - "name": "message", - "type": 6, - "optional": false - }, - { - "name": "offloadImages", - "type": 1, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 1, - "optional": true - }, - { - "name": "requestId", - "type": 6, - "optional": true - }, - { - "name": "status", - "type": 1, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 52, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 54, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 56, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "stop" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 58, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-calls" - }, - { - "kind": "object", - "properties": [ - { - "name": "blocks", - "type": 60, - "optional": true - }, - { - "name": "response", - "type": 61, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 61 - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "literal", - "value": "finish" - }, - { - "kind": "object", - "properties": [ - { - "name": "type", - "type": 64, - "optional": false - }, - { - "name": "usage", - "type": 65, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "usage" - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 1, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 1, - "optional": true - }, - { - "name": "inputTokens", - "type": 1, - "optional": false - }, - { - "name": "outputTokens", - "type": 1, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 1, - "optional": true - }, - { - "name": "totalTokens", - "type": 1, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "chunk" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 7, - "optional": false - }, - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "texts", - "type": 5, - "optional": false - }, - { - "name": "time0", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 68, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 7, - "optional": false - }, - { - "name": "index", - "type": 1, - "optional": false - }, - { - "name": "texts", - "type": 5, - "optional": false - }, - { - "name": "time0", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 70, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-chunks" - } - ] - }, - "names": [ - "event:assistant/attempt.data" - ], - "sources": [ - "packages/core/session/src/types.ts:335" - ] - }, { "digest": "0d47a8f3d847243c4488e755ad4cab7a04ac5d4621b9c81865524cf3f4d8536f", "schema": { @@ -16250,50 +22530,11 @@ } ] }, - "names": [ - "event:subagent/model-selection-policy.data" - ], + "names": [], "sources": [ "packages/subagent/tool-subagent/src/model-selection-state.ts:17" ] }, - { - "digest": "0ddab4577db37a3e0d9e3a91761735c8ef6f5629d526ab8ecaeeea19c097c8f8", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 1, - "optional": false - }, - { - "name": "plugin", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" - } - ] - }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[1]", - "event:system/message.data.message.source[0]" - ], - "sources": [] - }, { "digest": "0e10d7c096b47e61defe372a5fc8bd37d835199410eac44367f95c45082498bd", "schema": { @@ -16348,9 +22589,7 @@ } ] }, - "names": [ - "event:subagent/catalog.data[1]" - ], + "names": [], "sources": [] }, { @@ -16367,6 +22606,449 @@ "names": [], "sources": [] }, + { + "digest": "0ed8d1108fe7a5e1c3078ef1faea12199a56b6b1216ccaceb0f6103b0c9a7691", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-claude-code" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "0ee52de154f8955c7abc82cffebc57452dcc8c44dccbdb6ad16c71a11305ead8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "error", + "type": 30, + "optional": true + }, + { + "name": "isError", + "type": 31, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "parentCallId", + "type": 5, + "optional": false + }, + { + "name": "rootCallId", + "type": 5, + "optional": false + }, + { + "name": "subCallId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "reason", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + } + ] + }, + "names": [ + "packages/core/tools/src/types.ts#PtcDispatchEventData" + ], + "sources": [ + "packages/core/tools/src/types.ts:20" + ] + }, + { + "digest": "0eeb17e1df89b1ebc2902116fe7145e0d321ef0db26e6bdebc802cb8513a01c1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "runtime-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "0f46153645c297846a3fad3911636659ca4717a5e7d71c9f50bffacd312115ef", "schema": { @@ -16394,21 +23076,331 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].content[0][2].attachment.originalDimensions" - ], + "names": [], "sources": [ "packages/attachment/attachment/src/types.ts:28" ] }, { - "digest": "10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe", + "digest": "0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce", "schema": { "root": 0, "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 31, + "optional": true + }, + { + "name": "seq", + "type": 16, + "optional": false + }, + { + "name": "time", + "type": 16, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 5, + 7, + 9, + 11, + 13, + 18 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", - "value": "compaction/prune" + "value": "blocked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "forked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 14, + "optional": false + }, + { + "name": "kind", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 15, + "optional": false + }, + { + "name": "message", + "type": 15, + "optional": false + }, + { + "name": "offloadImages", + "type": 16, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 16, + "optional": true + }, + { + "name": "requestId", + "type": 15, + "optional": true + }, + { + "name": "status", + "type": 16, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 19, + "optional": false + }, + { + "name": "reason", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 21, + 23, + 25, + 27, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + }, + { + "name": "reason", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "turn/end" } ] }, @@ -16416,7 +23408,436 @@ "sources": [] }, { - "digest": "1169b301aaabcd992657b93ec93750c43175dda81ada5cac086f14f2eaaeed6d", + "digest": "0fe52387f65052702ed9d7cd59db826468936595d1b3eec207e7a823adc719db", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "plan-mode" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "100f6dca1468538239522cde3533e5bd721d0f1a7b50bea8b0eb533ea6c96163", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 19, + "optional": false + }, + { + "name": "time", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "error", + "type": 31, + "optional": true + }, + { + "name": "isError", + "type": 32, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "parentCallId", + "type": 6, + "optional": false + }, + { + "name": "rootCallId", + "type": 6, + "optional": false + }, + { + "name": "subCallId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 13, + 15, + 17, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "reason", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool/ptc-dispatch" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "1033093edd0db80ff410e00830b523405e00bb0c7684948e531ff65095799625", "schema": { "root": 0, "nodes": [ @@ -16440,7 +23861,7 @@ }, { "name": "surfaceOp", - "type": 76, + "type": 78, "optional": false }, { @@ -16450,7 +23871,7 @@ }, { "name": "type", - "type": 80, + "type": 82, "optional": false } ], @@ -16476,7 +23897,7 @@ }, { "name": "stream", - "type": 33, + "type": 35, "optional": false }, { @@ -16486,7 +23907,7 @@ }, { "name": "usage", - "type": 70, + "type": 72, "optional": true } ], @@ -16511,12 +23932,12 @@ }, { "name": "role", - "type": 29, + "type": 31, "optional": false }, { "name": "source", - "type": 30, + "type": 32, "optional": false } ], @@ -16533,8 +23954,9 @@ 9, 19, 22, - 25, - 27 + 24, + 26, + 29 ] }, { @@ -16723,40 +24145,6 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "isError", - "type": 23, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, { "kind": "object", "properties": [ @@ -16767,7 +24155,7 @@ }, { "name": "type", - "type": 26, + "type": 23, "optional": false } ], @@ -16787,7 +24175,7 @@ }, { "name": "type", - "type": 28, + "type": 25, "optional": false } ], @@ -16797,6 +24185,55 @@ "kind": "literal", "value": "text" }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, { "kind": "literal", "value": "assistant" @@ -16806,7 +24243,7 @@ "properties": [ { "name": "kind", - "type": 31, + "type": 33, "optional": false }, { @@ -16821,7 +24258,7 @@ }, { "name": "replayState", - "type": 32, + "type": 34, "optional": true } ], @@ -16837,15 +24274,15 @@ }, { "kind": "array", - "element": 34 + "element": 36 }, { "kind": "union", "types": [ - 35, - 39, - 72, - 74 + 37, + 41, + 74, + 76 ] }, { @@ -16853,12 +24290,12 @@ "properties": [ { "name": "args", - "type": 36, + "type": 38, "optional": false }, { "name": "dt", - "type": 37, + "type": 39, "optional": false }, { @@ -16883,7 +24320,7 @@ }, { "name": "type", - "type": 38, + "type": 40, "optional": false } ], @@ -16906,7 +24343,7 @@ "properties": [ { "name": "chunk", - "type": 40, + "type": 42, "optional": false }, { @@ -16916,7 +24353,7 @@ }, { "name": "type", - "type": 71, + "type": 73, "optional": false } ], @@ -16925,13 +24362,13 @@ { "kind": "union", "types": [ - 41, 43, 45, - 48, + 47, 50, 52, - 68 + 54, + 70 ] }, { @@ -16959,7 +24396,7 @@ }, { "name": "type", - "type": 42, + "type": 44, "optional": false } ], @@ -16984,7 +24421,7 @@ }, { "name": "type", - "type": 44, + "type": 46, "optional": false } ], @@ -16999,7 +24436,7 @@ "properties": [ { "name": "blockType", - "type": 46, + "type": 48, "optional": false }, { @@ -17007,42 +24444,6 @@ "type": 11, "optional": false }, - { - "name": "type", - "type": 47, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 8, - 18, - 21, - 24, - 26, - 28 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 11, - "optional": false - }, - { - "name": "text", - "type": 7, - "optional": false - }, { "name": "type", "type": 49, @@ -17051,9 +24452,21 @@ ], "indices": [] }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 23, + 25, + 28, + 30 + ] + }, { "kind": "literal", - "value": "reasoning-delta" + "value": "block-start" }, { "kind": "object", @@ -17076,6 +24489,31 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 53, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "text-delta" @@ -17085,17 +24523,17 @@ "properties": [ { "name": "reason", - "type": 53, + "type": 55, "optional": false }, { "name": "replayState", - "type": 65, + "type": 67, "optional": true }, { "name": "type", - "type": 67, + "type": 69, "optional": false } ], @@ -17104,11 +24542,11 @@ { "kind": "union", "types": [ - 54, - 57, + 56, 59, 61, - 63 + 63, + 65 ] }, { @@ -17116,12 +24554,12 @@ "properties": [ { "name": "failure", - "type": 55, + "type": 57, "optional": false }, { "name": "kind", - "type": 56, + "type": 58, "optional": false } ], @@ -17172,12 +24610,12 @@ "properties": [ { "name": "failure", - "type": 55, + "type": 57, "optional": false }, { "name": "kind", - "type": 58, + "type": 60, "optional": false } ], @@ -17192,7 +24630,7 @@ "properties": [ { "name": "kind", - "type": 60, + "type": 62, "optional": false } ], @@ -17207,7 +24645,7 @@ "properties": [ { "name": "kind", - "type": 62, + "type": 64, "optional": false } ], @@ -17222,7 +24660,7 @@ "properties": [ { "name": "kind", - "type": 64, + "type": 66, "optional": false } ], @@ -17237,12 +24675,12 @@ "properties": [ { "name": "blocks", - "type": 66, + "type": 68, "optional": true }, { "name": "response", - "type": 32, + "type": 34, "optional": false } ], @@ -17250,7 +24688,7 @@ }, { "kind": "array", - "element": 32 + "element": 34 }, { "kind": "literal", @@ -17261,12 +24699,12 @@ "properties": [ { "name": "type", - "type": 69, + "type": 71, "optional": false }, { "name": "usage", - "type": 70, + "type": 72, "optional": false } ], @@ -17321,7 +24759,7 @@ "properties": [ { "name": "dt", - "type": 37, + "type": 39, "optional": false }, { @@ -17331,42 +24769,7 @@ }, { "name": "texts", - "type": 36, - "optional": false - }, - { - "name": "time0", - "type": 11, - "optional": false - }, - { - "name": "type", - "type": 73, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 37, - "optional": false - }, - { - "name": "index", - "type": 11, - "optional": false - }, - { - "name": "texts", - "type": 36, + "type": 38, "optional": false }, { @@ -17382,6 +24785,41 @@ ], "indices": [] }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 39, + "optional": false + }, + { + "name": "index", + "type": 11, + "optional": false + }, + { + "name": "texts", + "type": 38, + "optional": false + }, + { + "name": "time0", + "type": 11, + "optional": false + }, + { + "name": "type", + "type": 77, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "text-chunks" @@ -17389,8 +24827,8 @@ { "kind": "union", "types": [ - 77, - 79 + 79, + 81 ] }, { @@ -17403,7 +24841,7 @@ }, { "name": "op", - "type": 78, + "type": 80, "optional": false }, { @@ -17428,9 +24866,84 @@ } ] }, - "names": [ - "event:assistant/message" - ], + "names": [], + "sources": [] + }, + { + "digest": "10e386801903f9d424602c31d3ff837a94aef623c8b391376d8d9e253525fabe", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "compaction/prune" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "11638dc58a31496fb6706ced3e23e3a2db1f3b2a8845968c810827a72b5fc811", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], "sources": [] }, { @@ -17494,9 +25007,7 @@ } ] }, - "names": [ - "event:hook/invoked.data" - ], + "names": [], "sources": [ "packages/hooks/hook-protocol/src/types.ts:19" ] @@ -17543,11 +25054,9 @@ } ] }, - "names": [ - "event:approval/policy.data" - ], + "names": [], "sources": [ - "packages/interaction/user-approval/src/index.ts:33" + "packages/interaction/user-approval/src/index.ts:40" ] }, { @@ -17694,17 +25203,17 @@ "packages/llm/llm/src/types.ts#ImageBlock" ], "sources": [ - "packages/llm/llm/src/types.ts:78" + "packages/llm/llm/src/types.ts:79" ] }, { - "digest": "137ac60e26bcb192210d9a32a704b73b0924ed34019323defa1b787be95bd45e", + "digest": "1379f0b72275994d20f1ddca2d60a96ab16ec80397ca9f1af21bdc67ba5c269c", "schema": { "root": 0, "nodes": [ { "kind": "literal", - "value": 3 + "value": "developer/message" } ] }, @@ -17806,9 +25315,7 @@ } ] }, - "names": [ - "event:deliverables/presented" - ], + "names": [], "sources": [] }, { @@ -17839,6 +25346,2781 @@ "names": [], "sources": [] }, + { + "digest": "1506a9b8224986c83015ae99d2cb5ede705538c58c063d6a48ef6d761a31ba6c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 27, + "optional": true + }, + { + "name": "seq", + "type": 20, + "optional": false + }, + { + "name": "time", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 199, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "inserted", + "type": 2, + "optional": false + }, + { + "name": "outcome", + "type": 195, + "optional": true + }, + { + "name": "removedCount", + "type": 20, + "optional": true + }, + { + "name": "start", + "type": 20, + "optional": false + }, + { + "name": "target", + "type": 196, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 32, + "optional": false + }, + { + "name": "source", + "type": 33, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 14, + 16, + 18, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 27, + "optional": true + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "mediaType", + "type": 21, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 26, + "optional": true + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 22, + 23, + 24, + 25 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 30, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 34, + 37, + 39, + 41, + 43, + 45, + 47, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 112, + 114, + 117, + 118, + 119, + 120, + 121, + 123, + 124, + 125, + 126, + 128, + 129, + 130, + 131, + 132, + 134, + 135, + 136, + 138, + 139, + 147, + 149, + 150, + 152, + 154, + 158, + 160, + 168, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 186, + 188, + 189, + 190, + 191, + 192, + 193, + 194 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 111, + "optional": false + }, + { + "name": "revision", + "type": 20, + "optional": false + }, + { + "name": "round", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 113, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 115, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 116, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 122, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 127, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 133, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 137, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 27, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 140, + "optional": false + }, + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 141 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 142, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 143, + 144, + 145 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 155, + "optional": false + }, + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 157, + "optional": false + }, + { + "name": "update", + "type": 27, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 69, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "references", + "type": 162, + "optional": false + }, + { + "name": "version", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 163 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 20, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 164, + "optional": false + }, + { + "name": "compacted", + "type": 166, + "optional": false + }, + { + "name": "inputIndex", + "type": 20, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 20, + "optional": false + }, + { + "name": "omittedMessages", + "type": 20, + "optional": false + }, + { + "name": "originalMessages", + "type": 20, + "optional": false + }, + { + "name": "retainedMessages", + "type": 20, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 166, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 165 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 171 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 185, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 187, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "canceled" + }, + { + "kind": "union", + "types": [ + 197, + 198 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + }, + { + "kind": "literal", + "value": "agent/inbox/spliced" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "15196447222782e773eb943c92b18316ce96b9af0f0cfddb6e57ba8274ecc5ff", "schema": { @@ -17934,9 +28216,7 @@ } ] }, - "names": [ - "event:command/done" - ], + "names": [], "sources": [] }, { @@ -17995,9 +28275,7 @@ } ] }, - "names": [ - "event:deliverables/presented.data" - ], + "names": [], "sources": [ "packages/deliverables/tool-present/src/types.ts:15" ] @@ -18030,6 +28308,919 @@ "names": [], "sources": [] }, + { + "digest": "15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "stream", + "type": 3, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 10, + 69, + 71 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 6, + "optional": false + }, + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 11, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 68, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 12, + 14, + 41, + 44, + 46, + 48, + 65 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 15, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 16, + 18, + 28, + 31, + 33, + 35, + 38 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 36, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 42, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 27, + 30, + 32, + 34, + 37, + 39 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 49, + "optional": false + }, + { + "name": "replayState", + "type": 61, + "optional": true + }, + { + "name": "type", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 50, + 53, + 55, + 57, + 59 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 51, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 7, + "optional": false + }, + { + "name": "message", + "type": 7, + "optional": false + }, + { + "name": "offloadImages", + "type": 2, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 2, + "optional": true + }, + { + "name": "requestId", + "type": 7, + "optional": true + }, + { + "name": "status", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 51, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 62, + "optional": true + }, + { + "name": "response", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 63 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 66, + "optional": false + }, + { + "name": "usage", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 2, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 2, + "optional": true + }, + { + "name": "inputTokens", + "type": 2, + "optional": false + }, + { + "name": "outputTokens", + "type": 2, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 2, + "optional": true + }, + { + "name": "totalTokens", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 70, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 8, + "optional": false + }, + { + "name": "index", + "type": 2, + "optional": false + }, + { + "name": "texts", + "type": 6, + "optional": false + }, + { + "name": "time0", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + }, + { + "kind": "literal", + "value": "assistant/attempt" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e", "schema": { @@ -18080,11 +29271,9 @@ } ] }, - "names": [ - "event:session/end-seed.data" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:405" + "packages/core/session/src/types.ts:427" ] }, { @@ -18221,7 +29410,7 @@ "packages/session/session-persistence-jsonl/src/format.ts#HeaderLine" ], "sources": [ - "packages/session/session-persistence-jsonl/src/format.ts:82" + "packages/session/session-persistence-jsonl/src/format.ts:83" ] }, { @@ -18266,6 +29455,40 @@ "names": [], "sources": [] }, + { + "digest": "1938c8c20f1cba7c82dbedcfa4f14c3ee191cd77ed3314ee1fc676d44cadf3be", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "schedule" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "1986c2664009c99155e44795676c887fa67f7c55cd2d5e6b648ff763e0ab033a", "schema": { @@ -18294,6 +29517,91 @@ "names": [], "sources": [] }, + { + "digest": "1a3440e3577382704d42a6263aa463504eb74c566734a55e9503a63efcd02445", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "agentPreset", + "type": 1, + "optional": true + }, + { + "name": "createdAt", + "type": 2, + "optional": false + }, + { + "name": "cwd", + "type": 1, + "optional": true + }, + { + "name": "delegationDepth", + "type": 2, + "optional": true + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "isSeeded", + "type": 3, + "optional": false + }, + { + "name": "origin", + "type": 4, + "optional": true + }, + { + "name": "parentSession", + "type": 1, + "optional": true + }, + { + "name": "version", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "subagent" + }, + { + "kind": "literal", + "value": 4 + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#SessionHeader" + ], + "sources": [ + "packages/core/session/src/types.ts:94" + ] + }, { "digest": "1ab2ef1296f157ba96998f179bb5daa9d21a82480da2901127aeab2730797c92", "schema": { @@ -18316,9 +29624,7 @@ } ] }, - "names": [ - "event:command/done.data.kind" - ], + "names": [], "sources": [] }, { @@ -18343,366 +29649,11 @@ } ] }, - "names": [ - "event:session/title.data.source[0]" - ], + "names": [], "sources": [ "packages/session/session-title/src/types.ts:29" ] }, - { - "digest": "1b573e2d5c094fa87e2a8bf409ddd4ac5ba92a123085e168de44b9ccdbd5244c", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "role", - "type": 28, - "optional": false - }, - { - "name": "source", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "tuple", - "elements": [ - { - "type": 2, - "optional": false, - "rest": false - } - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 26, - "optional": true - }, - { - "name": "toolCallId", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 2, - 5, - 8, - 10, - 12, - 23 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 13, - "optional": false - }, - { - "name": "offloaded", - "type": 21, - "optional": true - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 14, - "optional": false - }, - { - "name": "height", - "type": 14, - "optional": false - }, - { - "name": "mediaType", - "type": 15, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "originalDimensions", - "type": 20, - "optional": true - }, - { - "name": "width", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 16, - 17, - 18, - 19 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 14, - "optional": false - }, - { - "name": "width", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 24, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 14, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 6, - "optional": false - }, - { - "name": "kind", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - } - ] - }, - "names": [ - "packages/llm/llm/src/message.ts#ToolResultMessage" - ], - "sources": [ - "packages/llm/llm/src/message.ts:164" - ] - }, { "digest": "1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5", "schema": { @@ -18861,9 +29812,7 @@ } ] }, - "names": [ - "event:session/title" - ], + "names": [], "sources": [] }, { @@ -18894,6 +29843,965 @@ "names": [], "sources": [] }, + { + "digest": "1ccb56061942f5ccb0d30c9e4f2883b9d115ff906560029de637b61d3cde896d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "interrupted", + "type": 1, + "optional": true + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 10, + "optional": false + }, + { + "name": "stream", + "type": 34, + "optional": false + }, + { + "name": "turn", + "type": 10, + "optional": false + }, + { + "name": "usage", + "type": 71, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 18, + 21, + 23, + 25, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 1, + "optional": true + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 26, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 32, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "replayState", + "type": 33, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "array", + "element": 35 + }, + { + "kind": "union", + "types": [ + 36, + 40, + 73, + 75 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 37, + "optional": false + }, + { + "name": "dt", + "type": 38, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "time0", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 41, + "optional": false + }, + { + "name": "time", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 42, + 44, + 46, + 49, + 51, + 53, + 69 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "type", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 47, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 7, + 17, + 20, + 22, + 24, + 27, + 29 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 54, + "optional": false + }, + { + "name": "replayState", + "type": 66, + "optional": true + }, + { + "name": "type", + "type": 68, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 55, + 58, + 60, + 62, + 64 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 56, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "message", + "type": 6, + "optional": false + }, + { + "name": "offloadImages", + "type": 10, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 10, + "optional": true + }, + { + "name": "requestId", + "type": 6, + "optional": true + }, + { + "name": "status", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 56, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 65, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 67, + "optional": true + }, + { + "name": "response", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 33 + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 70, + "optional": false + }, + { + "name": "usage", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 10, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 10, + "optional": true + }, + { + "name": "inputTokens", + "type": 10, + "optional": false + }, + { + "name": "outputTokens", + "type": 10, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 10, + "optional": true + }, + { + "name": "totalTokens", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 38, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "texts", + "type": 37, + "optional": false + }, + { + "name": "time0", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 74, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 38, + "optional": false + }, + { + "name": "index", + "type": 10, + "optional": false + }, + { + "name": "texts", + "type": 37, + "optional": false + }, + { + "name": "time0", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 76, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:341" + ] + }, { "digest": "1cde1bedde79c5e8a56aee9c05c8e0a579cf5bc611deb85b93fa331a16ca978f", "schema": { @@ -18968,11 +30876,9 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6].reason[3]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:144" + "packages/llm/llm/src/types.ts:158" ] }, { @@ -19020,9 +30926,7 @@ } ] }, - "names": [ - "event:deliverables/presented.data.files" - ], + "names": [], "sources": [] }, { @@ -19232,6 +31136,40 @@ "names": [], "sources": [] }, + { + "digest": "1e709346005826eb81809eeb76a3f713cf13ad6c5cec75146d07020ab9adc938", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "schedule" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "1ebc6f9ff3aa9e3a38f8695f49bacdab1f8b7a3832741853ca46f40af56ccd01", "schema": { @@ -19260,6 +31198,20 @@ "names": [], "sources": [] }, + { + "digest": "1f1385dbc3e875c021e387c7096d671d606f22daec51b25c80348735b6bbfa10", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "repeat-tool-reminder" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0", "schema": { @@ -19365,11 +31317,11 @@ "packages/core/session/src/types.ts#TurnEndCancelCause" ], "sources": [ - "packages/core/session/src/types.ts:195" + "packages/core/session/src/types.ts:196" ] }, { - "digest": "2074f40221b76c75fd314246db558965dc3477dfb440bcc952b1eedc9778e366", + "digest": "1fdad624334d354820dfb3a26e28d0bc9fc1b62a33f87bab63f715b3f4391bfd", "schema": { "root": 0, "nodes": [ @@ -19377,495 +31329,14 @@ "kind": "object", "properties": [ { - "name": "message", + "name": "form", "type": 1, "optional": false }, { - "name": "step", - "type": 9, - "optional": false - }, - { - "name": "turn", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", + "name": "kind", "type": 2, "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "role", - "type": 28, - "optional": false - }, - { - "name": "source", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 4, - 7, - 18, - 21, - 24, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 8, - "optional": false - }, - { - "name": "offloaded", - "type": 16, - "optional": true - }, - { - "name": "type", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 9, - "optional": false - }, - { - "name": "height", - "type": 9, - "optional": false - }, - { - "name": "mediaType", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 15, - "optional": true - }, - { - "name": "width", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 11, - 12, - 13, - 14 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 9, - "optional": false - }, - { - "name": "width", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 19, - "optional": false - }, - { - "name": "type", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 22, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "system" - }, - { - "kind": "union", - "types": [ - 30, - 35, - 37, - 39, - 41, - 43, - 45 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 31, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "sections", - "type": 33, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 34 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "text", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 36, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 38, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 40, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false } ], "indices": [] @@ -19874,55 +31345,14 @@ "kind": "literal", "value": "relay" }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 44, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", - "value": "instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 32, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] + "value": "hooks-codex" } ] }, - "names": [ - "event:system/message.data" - ], - "sources": [ - "packages/core/session/src/types.ts:310" - ] + "names": [], + "sources": [] }, { "digest": "20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5", @@ -19946,11 +31376,9 @@ } ] }, - "names": [ - "event:plan/mode.data" - ], + "names": [], "sources": [ - "packages/plan/plan-mode/src/index.ts:47" + "packages/plan/plan-mode/src/index.ts:53" ] }, { @@ -20020,6 +31448,436 @@ "packages/experimental/agent-team/src/types.ts:115" ] }, + { + "digest": "21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 19, + "optional": false + }, + { + "name": "time", + "type": 19, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + }, + { + "name": "version", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "targetId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 13, + 15, + 17, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": 2 + }, + { + "kind": "literal", + "value": "team/message/queued" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "224aa11d4d5f88c450822d01b99e6ca5e3a9c7f26a5ede10bae33384a09ef4dc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "234142ee4f996f38cc9fa3b8b3e3de29b03c9aefe5ebf6c224eddd564505aa85", "schema": { @@ -20049,1316 +31907,56 @@ "sources": [] }, { - "digest": "23c7cce57d20589897f4e2bd5898affc6fc611b87cd0cc8b95be1cfdd8b3a7eb", + "digest": "23af3759678a30de1d11d946772da8c051c63caa67997c5da05d30d7a9fe8a97", "schema": { "root": 0, "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "role", - "type": 27, - "optional": false - }, - { - "name": "source", - "type": 31, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "union", - "types": [ - 3, - 6, - 17, - 20, - 23, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, { "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 7, - "optional": false - }, - { - "name": "offloaded", - "type": 15, - "optional": true - }, - { - "name": "type", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 8, - "optional": false - }, - { - "name": "height", - "type": 8, - "optional": false - }, - { - "name": "mediaType", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "originalDimensions", - "type": 14, - "optional": true - }, - { - "name": "width", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 10, - 11, - 12, - 13 - ] - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 8, - "optional": false - }, - { - "name": "width", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 18, - "optional": false - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 8, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "isError", - "type": 21, - "optional": true - }, - { - "name": "toolCallId", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "union", - "types": [ - 28, - 29, - 30 - ] - }, - { - "kind": "literal", - "value": "system" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 32, - 41, - 43, - 44, - 47, - 52, - 54, - 59, - 60, - 61, - 63, - 65, - 66, - 73, - 75, - 77, - 79, - 81, - 84, - 85 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 15, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 4, - "optional": true - }, - { - "name": "changes", - "type": 33, - "optional": false - }, - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 34 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 35, - "optional": false - }, - { - "name": "digest", - "type": 4, - "optional": true - }, - { - "name": "path", - "type": 4, - "optional": false - }, - { - "name": "scope", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 36, - 37, - 38 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 4, - "optional": false - }, - { - "name": "kind", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 4, - "optional": true - }, - { - "name": "kind", - "type": 30, - "optional": false - }, - { - "name": "rpcId", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 4, - "optional": false - }, - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 46, - "optional": false - }, - { - "name": "provider", - "type": 4, - "optional": false - }, - { - "name": "ruleId", - "type": 4, - "optional": false - }, - { - "name": "source", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 48, - "optional": false - }, - { - "name": "form", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - }, - { - "name": "update", - "type": 15, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 49 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 55, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "sections", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 58 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "text", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 64, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 67, - "optional": false - }, - { - "name": "references", - "type": 68, - "optional": false - }, - { - "name": "version", - "type": 72, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 69 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 8, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 70, - "optional": false - }, - { - "name": "compacted", - "type": 21, - "optional": false - }, - { - "name": "inputIndex", - "type": 8, - "optional": false - }, - { - "name": "label", - "type": 4, - "optional": false - }, - { - "name": "omittedBytes", - "type": 8, - "optional": false - }, - { - "name": "omittedMessages", - "type": 8, - "optional": false - }, - { - "name": "originalMessages", - "type": 8, - "optional": false - }, - { - "name": "retainedMessages", - "type": 8, - "optional": false - }, - { - "name": "sessionId", - "type": 4, - "optional": false - }, - { - "name": "truncated", - "type": 21, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 8, - 71 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 74, - "optional": false - }, - { - "name": "senderSessionId", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 64, - "optional": false - }, - { - "name": "kind", - "type": 76, - "optional": false - }, - { - "name": "senderSessionId", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 4, - "optional": false - }, - { - "name": "kind", - "type": 78, - "optional": false - }, - { - "name": "revision", - "type": 8, - "optional": false - }, - { - "name": "round", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 80, - "optional": false - }, - { - "name": "messageId", - "type": 4, - "optional": false - }, - { - "name": "senderId", - "type": 4, - "optional": false - }, - { - "name": "senderName", - "type": 4, - "optional": false - }, - { - "name": "teamId", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 82, - "optional": false - }, - { - "name": "model", - "type": 4, - "optional": false - }, - { - "name": "provider", - "type": 4, - "optional": false - }, - { - "name": "replayState", - "type": 83, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 30, - "optional": false - } - ], - "indices": [] + "value": "dsh-session-title-llm" } ] }, - "names": [ - "packages/llm/llm/src/message.ts#Message" - ], - "sources": [ - "packages/llm/llm/src/message.ts:131" - ] + "names": [], + "sources": [] }, { - "digest": "23cf7e0cf3fec1283b60fa15713506169bc9c079a08e124d1cb9733baca80b40", + "digest": "24b10f7cdae64928f89c49afc2eca0af9eb4a2f135e16f3416e6b8461fef1748", "schema": { "root": 0, "nodes": [ - { - "kind": "union", - "types": [ - 1, - 7, - 9, - 11, - 13, - 15, - 17 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 2, - "optional": false - }, - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "sections", - "type": 5, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "text", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 8, - "optional": false - }, - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 10, - "optional": false - }, - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 12, - "optional": false - }, - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 14, - "optional": false - }, - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 16, - "optional": false - }, - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 3, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] + "value": "runtime-context" } ] }, - "names": [ - "event:system/message.data.message.source" - ], + "names": [], + "sources": [] + }, + { + "digest": "24ce31aa528272e59f21cd26da9eca08968bcc97529756a749bfdab71746d9c8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + } + ] + }, + "names": [], "sources": [] }, { @@ -21543,6 +32141,40 @@ "names": [], "sources": [] }, + { + "digest": "260523b412c19ad8c2bb00093b07f64245ff8ba6b2f76c5b545303772ac9704c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "tool-goal" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78", "schema": { @@ -21628,9 +32260,7 @@ } ] }, - "names": [ - "event:approval/policy" - ], + "names": [], "sources": [] }, { @@ -21647,853 +32277,6 @@ "names": [], "sources": [] }, - { - "digest": "26f3bb7529cfce1e3a0f1ededa365d8b426758ca0feeb0beabeee805f8bb8346", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "array", - "element": 1 - }, - { - "kind": "union", - "types": [ - 2, - 8, - 66, - 68 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "args", - "type": 3, - "optional": false - }, - { - "name": "dt", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "time0", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "tool-call-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "chunk", - "type": 9, - "optional": false - }, - { - "name": "time", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 65, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 10, - 12, - 38, - 41, - 43, - 45, - 62 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "argumentsDelta", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 13, - "optional": false - }, - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 37, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 14, - 16, - 26, - 29, - 33, - 35 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 17, - "optional": false - }, - { - "name": "offloaded", - "type": 24, - "optional": true - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 6, - "optional": false - }, - { - "name": "height", - "type": 6, - "optional": false - }, - { - "name": "mediaType", - "type": 18, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "originalDimensions", - "type": 23, - "optional": true - }, - { - "name": "width", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 19, - 20, - 21, - 22 - ] - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 6, - "optional": false - }, - { - "name": "width", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 27, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 30, - "optional": false - }, - { - "name": "isError", - "type": 31, - "optional": true - }, - { - "name": "toolCallId", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 32, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 13 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 34, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 36, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "block-end" - }, - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 39, - "optional": false - }, - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 15, - 25, - 28, - 32, - 34, - 36 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 44, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 46, - "optional": false - }, - { - "name": "replayState", - "type": 58, - "optional": true - }, - { - "name": "type", - "type": 61, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 47, - 50, - 52, - 54, - 56 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 49, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 4, - "optional": false - }, - { - "name": "message", - "type": 4, - "optional": false - }, - { - "name": "offloadImages", - "type": 6, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 6, - "optional": true - }, - { - "name": "requestId", - "type": 4, - "optional": true - }, - { - "name": "status", - "type": 6, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 53, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "stop" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-calls" - }, - { - "kind": "object", - "properties": [ - { - "name": "blocks", - "type": 59, - "optional": true - }, - { - "name": "response", - "type": 60, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 60 - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "literal", - "value": "finish" - }, - { - "kind": "object", - "properties": [ - { - "name": "type", - "type": 63, - "optional": false - }, - { - "name": "usage", - "type": 64, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "usage" - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 6, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 6, - "optional": true - }, - { - "name": "inputTokens", - "type": 6, - "optional": false - }, - { - "name": "outputTokens", - "type": 6, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 6, - "optional": true - }, - { - "name": "totalTokens", - "type": 6, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "chunk" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 5, - "optional": false - }, - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "texts", - "type": 3, - "optional": false - }, - { - "name": "time0", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 67, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 5, - "optional": false - }, - { - "name": "index", - "type": 6, - "optional": false - }, - { - "name": "texts", - "type": 3, - "optional": false - }, - { - "name": "time0", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 69, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-chunks" - } - ] - }, - "names": [ - "event:assistant/attempt.data.stream", - "event:assistant/message.data.stream" - ], - "sources": [] - }, { "digest": "2765e9119edf5816ac1ab4c95c5ee32c90403f3742962eff11544f7752d59d2e", "schema": { @@ -22601,15 +32384,13 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6].reason[4]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:145" + "packages/llm/llm/src/types.ts:159" ] }, { - "digest": "29af48b840d0cd9e48b6f50bf3b354f8f6340607c5b99220a48e74f60beac9e2", + "digest": "28936c614bd4e7e2774806edcbb3cbfd3ee643ac1cbf0bbdff43d915505a8fe3", "schema": { "root": 0, "nodes": [ @@ -22617,91 +32398,47 @@ "kind": "object", "properties": [ { - "name": "data", + "name": "form", "type": 1, "optional": false }, { - "name": "ignorable", - "type": 24, - "optional": true - }, - { - "name": "seq", - "type": 17, - "optional": false - }, - { - "name": "sourceEventSeqs", - "type": 38, - "optional": true - }, - { - "name": "surfaceOp", - "type": 39, - "optional": false - }, - { - "name": "time", - "type": 17, - "optional": false - }, - { - "name": "type", - "type": 43, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "error", + "name": "kind", "type": 2, - "optional": true - }, - { - "name": "message", - "type": 4, "optional": false }, { - "name": "meta", - "type": 34, - "optional": true - }, - { - "name": "step", - "type": 17, - "optional": false - }, - { - "name": "turn", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", + "name": "sections", "type": 3, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ { "name": "name", - "type": 3, + "type": 5, "optional": false }, { - "name": "reason", - "type": 3, - "optional": true + "name": "text", + "type": 5, + "optional": false } ], "indices": [] @@ -22709,95 +32446,23 @@ { "kind": "primitive", "type": "string" - }, + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "290f32bfd81ff85a8095886a8066fae06e885942b63a8bcd6a8d66d328445808", + "schema": { + "root": 0, + "nodes": [ { "kind": "object", "properties": [ { - "name": "content", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 3, - "optional": false - }, - { - "name": "role", - "type": 31, - "optional": false - }, - { - "name": "source", - "type": 32, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "tuple", - "elements": [ - { - "type": 6, - "optional": false, - "rest": false - } - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 7, - "optional": false - }, - { - "name": "isError", - "type": 29, - "optional": true - }, - { - "name": "toolCallId", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 8 - }, - { - "kind": "union", - "types": [ - 6, - 9, - 11, - 13, - 15, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 10, + "name": "kind", + "type": 1, "optional": false } ], @@ -22805,237 +32470,29 @@ }, { "kind": "literal", - "value": "text" - }, + "value": "dsh-session-title-llm" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "297fbd8067d7815adae02b89790ec6ff5fb7c2cb0d0eb026e1746c24ec857761", + "schema": { + "root": 0, + "nodes": [ { "kind": "object", "properties": [ { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 16, - "optional": false - }, - { - "name": "offloaded", - "type": 24, - "optional": true - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 3, - "optional": false - }, - { - "name": "bytes", - "type": 17, - "optional": false - }, - { - "name": "height", - "type": 17, - "optional": false - }, - { - "name": "mediaType", - "type": 18, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": true - }, - { - "name": "originalDimensions", - "type": 23, - "optional": true - }, - { - "name": "width", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 19, - 20, - 21, - 22 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 17, - "optional": false - }, - { - "name": "width", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 27, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 3, - "optional": false - }, - { - "name": "bytes", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 3, + "name": "form", + "type": 1, "optional": false }, { "name": "kind", - "type": 33, + "type": 2, "optional": false } ], @@ -23043,86 +32500,15 @@ }, { "kind": "literal", - "value": "tool" - }, - { - "kind": "union", - "types": [ - 3, - 17, - 29, - 35, - 36, - 37 - ] - }, - { - "kind": "array", - "element": 34 - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "object", - "properties": [], - "indices": [ - { - "key": 3, - "value": 34 - } - ] - }, - { - "kind": "array", - "element": 17 - }, - { - "kind": "union", - "types": [ - 40, - 41 - ] + "value": "catalog" }, { "kind": "literal", - "value": "append" - }, - { - "kind": "object", - "properties": [ - { - "name": "endSeq", - "type": 17, - "optional": false - }, - { - "name": "op", - "type": 42, - "optional": false - }, - { - "name": "startSeq", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "tool/result" + "value": "hooks-claude-code" } ] }, - "names": [ - "event:tool/result" - ], + "names": [], "sources": [] }, { @@ -23401,13 +32787,11 @@ } ] }, - "names": [ - "event:schedule/change" - ], + "names": [], "sources": [] }, { - "digest": "2a8b114637e66faab5fae1c6e2fba65320db6224c80f5f36c5bf32f937154d03", + "digest": "2aad1179f957631477b582e57cd8f538cb82618fc3fb816bde1171154235b065", "schema": { "root": 0, "nodes": [ @@ -23415,47 +32799,45 @@ "kind": "object", "properties": [ { - "name": "agentPreset", - "type": 1, - "optional": true - }, - { - "name": "createdAt", - "type": 2, - "optional": false - }, - { - "name": "cwd", - "type": 1, - "optional": true - }, - { - "name": "delegationDepth", - "type": 2, - "optional": true - }, - { - "name": "id", + "name": "form", "type": 1, "optional": false }, { - "name": "isSeeded", + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", "type": 3, "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false }, { - "name": "origin", - "type": 4, - "optional": true - }, - { - "name": "parentSession", - "type": 1, - "optional": true - }, - { - "name": "version", + "name": "text", "type": 5, "optional": false } @@ -23465,31 +32847,11 @@ { "kind": "primitive", "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "subagent" - }, - { - "kind": "literal", - "value": 3 } ] }, - "names": [ - "packages/core/session/src/types.ts#SessionHeader" - ], - "sources": [ - "packages/core/session/src/types.ts:93" - ] + "names": [], + "sources": [] }, { "digest": "2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee", @@ -23552,9 +32914,7 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[16].changes" - ], + "names": [], "sources": [] }, { @@ -23597,11 +32957,9 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[2]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:429" + "packages/llm/llm/src/types.ts:443" ] }, { @@ -23646,52 +33004,6 @@ "names": [], "sources": [] }, - { - "digest": "2ce7ef3b3daebf95815c7ae454a751d3e67ca7a22e2e0734fe2942df393bb66c", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 1, - "optional": false - }, - { - "name": "kind", - "type": 2, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" - } - ] - }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[6]", - "event:system/message.data.message.source[5]" - ], - "sources": [] - }, { "digest": "2d11ca7b0d4493e244b74eba093227866b33249841e59a1e9bf56afed38604c3", "schema": { @@ -23732,9 +33044,7 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request.data.body.tools[0]" - ], + "names": [], "sources": [ "packages/web/web-search-deepseek/src/provider.ts:71" ] @@ -23768,7 +33078,7 @@ "sources": [] }, { - "digest": "2f0aefb72ab453c4bf21a6687f436775d359dc6f8f10410fd4c0615b20bd9d76", + "digest": "2eafefdc6f79a4922d68a787a09eaf4dd2b2369c3777fba4c05e800b5678ac8e", "schema": { "root": 0, "nodes": [ @@ -23776,96 +33086,230 @@ "kind": "object", "properties": [ { - "name": "header", + "name": "content", "type": 1, "optional": false }, { - "name": "reason", - "type": 12, - "optional": false - }, - { - "name": "startsSeries", - "type": 3, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "adapterDefaults", - "type": 2, - "optional": true - }, - { - "name": "config", + "name": "id", "type": 4, "optional": false }, { - "name": "tools", - "type": 8, - "optional": true + "name": "senderId", + "type": 4, + "optional": false + }, + { + "name": "senderName", + "type": 4, + "optional": false + }, + { + "name": "targetId", + "type": 4, + "optional": false } ], "indices": [] }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 8, + 11, + 13, + 15, + 26 + ] + }, { "kind": "object", "properties": [ { - "name": "maxTokens", - "type": 3, - "optional": true + "name": "text", + "type": 4, + "optional": false }, { - "name": "reasoningEffort", - "type": 3, - "optional": true + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false } ], "indices": [] }, { "kind": "literal", - "value": true + "value": "text" }, { "kind": "object", "properties": [ { - "name": "maxTokens", - "type": 5, + "name": "tool", + "type": 9, "optional": true }, { - "name": "model", - "type": 6, + "name": "toolName", + "type": 4, "optional": false }, { - "name": "provider", - "type": 6, + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, "optional": false }, { - "name": "reasoningEffort", - "type": 6, + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, "optional": true }, { - "name": "stop", - "type": 7, + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 4, "optional": true }, { - "name": "temperature", - "type": 5, + "name": "originalDimensions", + "type": 23, "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false } ], "indices": [] @@ -23875,33 +33319,65 @@ "type": "number" }, { - "kind": "primitive", - "type": "string" + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] }, { - "kind": "array", - "element": 6 + "kind": "literal", + "value": "image/gif" }, { - "kind": "array", - "element": 9 + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" }, { "kind": "object", "properties": [ { - "name": "description", - "type": 6, + "name": "height", + "type": 17, "optional": false }, { - "name": "name", - "type": 6, + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, "optional": false }, { - "name": "parameters", - "type": 10, + "name": "type", + "type": 28, "optional": false } ], @@ -23909,50 +33385,36 @@ }, { "kind": "object", - "properties": [], - "indices": [ + "properties": [ { - "key": 6, - "value": 11 + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false } - ] - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "union", - "types": [ - 13, - 14, - 15, - 16 - ] + ], + "indices": [] }, { "kind": "literal", - "value": "resume" - }, - { - "kind": "literal", - "value": "series" - }, - { - "kind": "literal", - "value": "change" - }, - { - "kind": "literal", - "value": "initial" + "value": "file" } ] }, "names": [ - "event:request/header.data" + "packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot" ], "sources": [ - "packages/core/session/src/types.ts:370" + "packages/experimental/agent-team/src/types.ts:106" ] }, { @@ -23995,49 +33457,17 @@ ] }, { - "digest": "2f90a7b3646fea3e677bd7b4000aa96f3b8964f107b614e204e11ad4051c24fc", + "digest": "2f3f201c8846e19c20bb75c02280e3d4eb3c57509e4715f0c0a4d1d4f91a7a06", "schema": { "root": 0, "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 1, - "optional": false - }, - { - "name": "kind", - "type": 2, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" + "value": "tool-goal" } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[3]", - "event:system/message.data.message.source[2]" - ], + "names": [], "sources": [] }, { @@ -24093,1612 +33523,6 @@ "packages/core/tools/src/types.ts:11" ] }, - { - "digest": "300341f890f7b9506a1749fff4fa5239d16ea1c63ff6b15851acb03c20f3b48d", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "array", - "element": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "role", - "type": 28, - "optional": false - }, - { - "name": "source", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 4, - 7, - 18, - 21, - 24, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 8, - "optional": false - }, - { - "name": "offloaded", - "type": 16, - "optional": true - }, - { - "name": "type", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 9, - "optional": false - }, - { - "name": "height", - "type": 9, - "optional": false - }, - { - "name": "mediaType", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 15, - "optional": true - }, - { - "name": "width", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 11, - 12, - 13, - 14 - ] - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 9, - "optional": false - }, - { - "name": "width", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 19, - "optional": false - }, - { - "name": "type", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 22, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 30, - 39, - 41, - 42, - 45, - 50, - 52, - 57, - 58, - 59, - 61, - 63, - 64, - 71, - 73, - 75, - 77, - 79, - 82, - 83 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 16, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 5, - "optional": true - }, - { - "name": "changes", - "type": 31, - "optional": false - }, - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 38, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 32 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 33, - "optional": false - }, - { - "name": "digest", - "type": 5, - "optional": true - }, - { - "name": "path", - "type": 5, - "optional": false - }, - { - "name": "scope", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 34, - 35, - 36 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 5, - "optional": false - }, - { - "name": "kind", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 5, - "optional": true - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "rpcId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 5, - "optional": false - }, - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 44, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "ruleId", - "type": 5, - "optional": false - }, - { - "name": "source", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 46, - "optional": false - }, - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 49, - "optional": false - }, - { - "name": "update", - "type": 16, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 47 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 53, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "sections", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 56 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "text", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 60, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 60, - "optional": false - }, - { - "name": "kind", - "type": 65, - "optional": false - }, - { - "name": "references", - "type": 66, - "optional": false - }, - { - "name": "version", - "type": 70, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 67 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 9, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 68, - "optional": false - }, - { - "name": "compacted", - "type": 22, - "optional": false - }, - { - "name": "inputIndex", - "type": 9, - "optional": false - }, - { - "name": "label", - "type": 5, - "optional": false - }, - { - "name": "omittedBytes", - "type": 9, - "optional": false - }, - { - "name": "omittedMessages", - "type": 9, - "optional": false - }, - { - "name": "originalMessages", - "type": 9, - "optional": false - }, - { - "name": "retainedMessages", - "type": 9, - "optional": false - }, - { - "name": "sessionId", - "type": 5, - "optional": false - }, - { - "name": "truncated", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 9, - 69 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 72, - "optional": false - }, - { - "name": "senderSessionId", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 74, - "optional": false - }, - { - "name": "senderSessionId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 5, - "optional": false - }, - { - "name": "kind", - "type": 76, - "optional": false - }, - { - "name": "revision", - "type": 9, - "optional": false - }, - { - "name": "round", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 78, - "optional": false - }, - { - "name": "messageId", - "type": 5, - "optional": false - }, - { - "name": "senderId", - "type": 5, - "optional": false - }, - { - "name": "senderName", - "type": 5, - "optional": false - }, - { - "name": "teamId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 80, - "optional": false - }, - { - "name": "model", - "type": 5, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "replayState", - "type": 81, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 28, - "optional": false - } - ], - "indices": [] - } - ] - }, - "names": [ - "event:agent/inbox/spliced.data.inserted" - ], - "sources": [] - }, - { - "digest": "302b01ddddcbb3b16cfa3fba2a5d99f5082a55fbd9dc5c83a179a228b8a6a0ca", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "role", - "type": 27, - "optional": false - }, - { - "name": "source", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "union", - "types": [ - 3, - 6, - 17, - 20, - 23, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 7, - "optional": false - }, - { - "name": "offloaded", - "type": 15, - "optional": true - }, - { - "name": "type", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 8, - "optional": false - }, - { - "name": "height", - "type": 8, - "optional": false - }, - { - "name": "mediaType", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "originalDimensions", - "type": 14, - "optional": true - }, - { - "name": "width", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 10, - 11, - 12, - 13 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 8, - "optional": false - }, - { - "name": "width", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 18, - "optional": false - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 8, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "isError", - "type": 21, - "optional": true - }, - { - "name": "toolCallId", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "system" - }, - { - "kind": "union", - "types": [ - 29, - 34, - 36, - 38, - 40, - 42, - 44 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 30, - "optional": false - }, - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "sections", - "type": 32, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 33 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "text", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 35, - "optional": false - }, - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 41, - "optional": false - }, - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 31, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - } - ] - }, - "names": [ - "packages/llm/llm/src/message.ts#SystemMessage" - ], - "sources": [ - "packages/llm/llm/src/message.ts:158" - ] - }, { "digest": "30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f", "schema": { @@ -25797,7 +33621,7 @@ ] }, { - "digest": "314765bdff29c7862fb6ce820f1773563ba3094a680d163ea21180a2591b8578", + "digest": "312aee2f0c42aabbae6cc60d92d596d8453c0aeb061c5868d1755a69ef49e69a", "schema": { "root": 0, "nodes": [ @@ -25805,543 +33629,18 @@ "kind": "object", "properties": [ { - "name": "data", + "name": "form", "type": 1, "optional": false }, { - "name": "ignorable", - "type": 16, - "optional": true - }, - { - "name": "seq", - "type": 9, - "optional": false - }, - { - "name": "sourceEventSeqs", - "type": 84, - "optional": true - }, - { - "name": "surfaceOp", - "type": 85, - "optional": false - }, - { - "name": "time", - "type": 9, - "optional": false - }, - { - "name": "type", - "type": 88, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", + "name": "kind", "type": 2, "optional": false }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "role", - "type": 28, - "optional": false - }, - { - "name": "source", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 4, - 7, - 18, - 21, - 24, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 8, - "optional": false - }, - { - "name": "offloaded", - "type": 16, - "optional": true - }, - { - "name": "type", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 9, - "optional": false - }, - { - "name": "height", - "type": 9, - "optional": false - }, - { - "name": "mediaType", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 15, - "optional": true - }, - { - "name": "width", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 11, - 12, - 13, - 14 - ] - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 9, - "optional": false - }, - { - "name": "width", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 19, - "optional": false - }, - { - "name": "type", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 22, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 30, - 39, - 41, - 42, - 45, - 50, - 52, - 57, - 58, - 59, - 61, - 63, - 64, - 71, - 73, - 75, - 77, - 79, - 82, - 83 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 16, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 5, - "optional": true - }, - { - "name": "changes", - "type": 31, - "optional": false - }, - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 38, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 32 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 33, - "optional": false - }, - { - "name": "digest", - "type": 5, - "optional": true - }, - { - "name": "path", - "type": 5, - "optional": false - }, - { - "name": "scope", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 34, - 35, - 36 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 5, - "optional": false - }, - { - "name": "kind", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 5, - "optional": true - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "rpcId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 5, - "optional": false - }, - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 44, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "ruleId", - "type": 5, - "optional": false - }, - { - "name": "source", - "type": 5, - "optional": false - }, { "name": "summary", - "type": 5, + "type": 3, "optional": false } ], @@ -26353,596 +33652,59 @@ }, { "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 46, - "optional": false - }, - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 49, - "optional": false - }, - { - "name": "update", - "type": 16, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 47 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 53, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "sections", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 56 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "text", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 60, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 60, - "optional": false - }, - { - "name": "kind", - "type": 65, - "optional": false - }, - { - "name": "references", - "type": 66, - "optional": false - }, - { - "name": "version", - "type": 70, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 67 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 9, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 68, - "optional": false - }, - { - "name": "compacted", - "type": 22, - "optional": false - }, - { - "name": "inputIndex", - "type": 9, - "optional": false - }, - { - "name": "label", - "type": 5, - "optional": false - }, - { - "name": "omittedBytes", - "type": 9, - "optional": false - }, - { - "name": "omittedMessages", - "type": 9, - "optional": false - }, - { - "name": "originalMessages", - "type": 9, - "optional": false - }, - { - "name": "retainedMessages", - "type": 9, - "optional": false - }, - { - "name": "sessionId", - "type": 5, - "optional": false - }, - { - "name": "truncated", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 9, - 69 - ] + "value": "schedule" }, { "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "31907de9563751822af6d9be02bafaf26faa098bbd1cb412524134d577cc1648", + "schema": { + "root": 0, + "nodes": [ { "kind": "object", "properties": [ { - "name": "form", - "type": 43, + "name": "compactionId", + "type": 1, "optional": false }, { "name": "kind", - "type": 72, + "type": 2, "optional": false }, { - "name": "senderSessionId", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 74, - "optional": false - }, - { - "name": "senderSessionId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 5, - "optional": false - }, - { - "name": "kind", - "type": 76, - "optional": false - }, - { - "name": "revision", - "type": 9, - "optional": false - }, - { - "name": "round", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 78, - "optional": false - }, - { - "name": "messageId", - "type": 5, - "optional": false - }, - { - "name": "senderId", - "type": 5, - "optional": false - }, - { - "name": "senderName", - "type": 5, - "optional": false - }, - { - "name": "teamId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 80, - "optional": false - }, - { - "name": "model", - "type": 5, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "replayState", - "type": 81, + "name": "sourceCommandId", + "type": 1, "optional": true } ], "indices": [] }, { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 9 - }, - { - "kind": "union", - "types": [ - 86, - 87 - ] + "kind": "primitive", + "type": "string" }, { "kind": "literal", - "value": "append" - }, - { - "kind": "object", - "properties": [ - { - "name": "endSeq", - "type": 9, - "optional": false - }, - { - "name": "op", - "type": 35, - "optional": false - }, - { - "name": "startSeq", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "user/message" + "value": "compact-checkpoint" } ] }, "names": [ - "event:user/message" + "packages/compaction/compaction/src/checkpoint.ts#CompactionCheckpointSource" ], - "sources": [] + "sources": [ + "packages/compaction/compaction/src/checkpoint.ts:22" + ] }, { "digest": "326a9bfda27dda5882fb3cbe6e715df41dae2298fdae3d66437457268a665693", @@ -27025,12 +33787,866 @@ } ] }, - "names": [ - "event:feedback/message-put.data.item.category", - "event:feedback/record.data.category" - ], + "names": [], "sources": [] }, + { + "digest": "33341aac09312300de5a178e6cc6f6544a4876f7f710cfea55eda473c8d329ef", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 7, + 66, + 68 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 2, + "optional": false + }, + { + "name": "dt", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "time0", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 8, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 65, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 9, + 11, + 38, + 41, + 43, + 45, + 62 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 12, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 15, + 25, + 28, + 30, + 32, + 35 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 33, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 39, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 14, + 24, + 27, + 29, + 31, + 34, + 36 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 46, + "optional": false + }, + { + "name": "replayState", + "type": 58, + "optional": true + }, + { + "name": "type", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 47, + 50, + 52, + 54, + 56 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "offloadImages", + "type": 5, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 5, + "optional": true + }, + { + "name": "requestId", + "type": 3, + "optional": true + }, + { + "name": "status", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 48, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 59, + "optional": true + }, + { + "name": "response", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 60 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 63, + "optional": false + }, + { + "name": "usage", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 5, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 5, + "optional": true + }, + { + "name": "inputTokens", + "type": 5, + "optional": false + }, + { + "name": "outputTokens", + "type": 5, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 5, + "optional": true + }, + { + "name": "totalTokens", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "texts", + "type": 2, + "optional": false + }, + { + "name": "time0", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 4, + "optional": false + }, + { + "name": "index", + "type": 5, + "optional": false + }, + { + "name": "texts", + "type": 2, + "optional": false + }, + { + "name": "time0", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [ + "packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord" + ], + "sources": [ + "packages/llm/llm/src/assistant-stream.ts:20" + ] + }, { "digest": "335e242de1fcc17b6ca920fc420d71bec2d76e53e37955c00948b65ab77f05c5", "schema": { @@ -27082,7 +34698,7 @@ "packages/core/session/src/types.ts#SurfaceOp" ], "sources": [ - "packages/core/session/src/types.ts:439" + "packages/core/session/src/types.ts:462" ] }, { @@ -27174,445 +34790,9 @@ } ] }, - "names": [ - "event:model/selection" - ], + "names": [], "sources": [] }, - { - "digest": "356aad27134a0e31af67c994ff8b9e4b91acfb6c4917b3bc1f7a62bbf82794d5", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "error", - "type": 1, - "optional": true - }, - { - "name": "message", - "type": 3, - "optional": false - }, - { - "name": "meta", - "type": 33, - "optional": true - }, - { - "name": "step", - "type": 16, - "optional": false - }, - { - "name": "turn", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - }, - { - "name": "reason", - "type": 2, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 2, - "optional": false - }, - { - "name": "role", - "type": 30, - "optional": false - }, - { - "name": "source", - "type": 31, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "tuple", - "elements": [ - { - "type": 5, - "optional": false, - "rest": false - } - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 6, - "optional": false - }, - { - "name": "isError", - "type": 28, - "optional": true - }, - { - "name": "toolCallId", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 7 - }, - { - "kind": "union", - "types": [ - 5, - 8, - 10, - 12, - 14, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 15, - "optional": false - }, - { - "name": "offloaded", - "type": 23, - "optional": true - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 16, - "optional": false - }, - { - "name": "height", - "type": 16, - "optional": false - }, - { - "name": "mediaType", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": true - }, - { - "name": "originalDimensions", - "type": 22, - "optional": true - }, - { - "name": "width", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 18, - 19, - 20, - 21 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 16, - "optional": false - }, - { - "name": "width", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 26, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 2, - "optional": false - }, - { - "name": "kind", - "type": 32, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "union", - "types": [ - 2, - 16, - 28, - 34, - 35, - 36 - ] - }, - { - "kind": "array", - "element": 33 - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "object", - "properties": [], - "indices": [ - { - "key": 2, - "value": 33 - } - ] - } - ] - }, - "names": [ - "event:tool/result.data" - ], - "sources": [ - "packages/core/session/src/types.ts:355" - ] - }, { "digest": "36d6a9a871d949ea4f3edd919d81d66aa69218bebef38899d2a1282c39420a1f", "schema": { @@ -27722,9 +34902,7 @@ } ] }, - "names": [ - "event:command/run" - ], + "names": [], "sources": [] }, { @@ -27833,9 +35011,7 @@ } ] }, - "names": [ - "event:llm/retry.data[1]" - ], + "names": [], "sources": [ "packages/llm/llm-retry/src/types.ts:30" ] @@ -27938,9 +35114,7 @@ } ] }, - "names": [ - "event:request/context" - ], + "names": [], "sources": [] }, { @@ -28025,9 +35199,7 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][2]" - ], + "names": [], "sources": [ "packages/llm/llm/src/assistant-stream.ts:35" ] @@ -28061,414 +35233,6 @@ "packages/feedback/message-feedback/src/types.ts:17" ] }, - { - "digest": "3aa261c8516b5c955ed12080e6257a56cbe513f6c9f0ac9274c12e96c196ebca", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "compactionId", - "type": 1, - "optional": false - }, - { - "name": "maxTokens", - "type": 2, - "optional": true - }, - { - "name": "model", - "type": 1, - "optional": false - }, - { - "name": "provider", - "type": 1, - "optional": false - }, - { - "name": "rawOutput", - "type": 3, - "optional": true - }, - { - "name": "shadowedRange", - "type": 27, - "optional": false - }, - { - "name": "shadowedSeqs", - "type": 28, - "optional": false - }, - { - "name": "shadowedTokenCount", - "type": 2, - "optional": false - }, - { - "name": "sourceCommandId", - "type": 1, - "optional": true - }, - { - "name": "summary", - "type": 3, - "optional": false - }, - { - "name": "usage", - "type": 29, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 5, - 8, - 10, - 12, - 14, - 24 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 6, - "optional": true - }, - { - "name": "toolCallId", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 15, - "optional": false - }, - { - "name": "offloaded", - "type": 22, - "optional": true - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 1, - "optional": false - }, - { - "name": "bytes", - "type": 2, - "optional": false - }, - { - "name": "height", - "type": 2, - "optional": false - }, - { - "name": "mediaType", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": true - }, - { - "name": "originalDimensions", - "type": 21, - "optional": true - }, - { - "name": "width", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 17, - 18, - 19, - 20 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 2, - "optional": false - }, - { - "name": "width", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 25, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 1, - "optional": false - }, - { - "name": "bytes", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "end", - "type": 2, - "optional": false - }, - { - "name": "start", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 2, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 2, - "optional": true - }, - { - "name": "inputTokens", - "type": 2, - "optional": false - }, - { - "name": "outputTokens", - "type": 2, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 2, - "optional": true - }, - { - "name": "totalTokens", - "type": 2, - "optional": true - } - ], - "indices": [] - } - ] - }, - "names": [ - "event:compaction/summary.data[1]" - ], - "sources": [] - }, { "digest": "3ac1196f59d5e9e0e9345122c8c403b102478b526404a2e591a38f613483321e", "schema": { @@ -28572,6 +35336,40 @@ "packages/subagent/subagent/src/catalog.ts:24" ] }, + { + "digest": "3b04790e08b35241ffa0d38f6d7e4f8788aa921341f6c0d7574a329397c59408", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "plan-mode" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48", "schema": { @@ -28657,9 +35455,41 @@ } ] }, - "names": [ - "event:tool/call" - ], + "names": [], + "sources": [] + }, + { + "digest": "3b4f2c9ef2c1217eac596c7b070173cb7896e2fae09e729bc7c56c801e56bb29", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "hooks-codex" + } + ] + }, + "names": [], "sources": [] }, { @@ -28699,12 +35529,154 @@ ] }, "names": [ - "event:compaction/end.data.turn", - "event:compaction/start.data.turn", "packages/core/session/src/types.ts#OptionalSessionSeq" ], "sources": [ - "packages/core/session/src/types.ts:64" + "packages/core/session/src/types.ts:65" + ] + }, + { + "digest": "3bdb8dc6989655b0d4ec361edafb8e2629bc263e1ea591819414fdafc1a413b3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 1, + "optional": false + }, + { + "name": "index", + "type": 9, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "block-start" + } + ] + }, + "names": [], + "sources": [ + "packages/llm/llm/src/types.ts:441" ] }, { @@ -28787,9 +35759,7 @@ } ] }, - "names": [ - "event:approval/asked" - ], + "names": [], "sources": [] }, { @@ -28841,7 +35811,7 @@ "packages/core/tools/src/index.ts#ToolRestriction" ], "sources": [ - "packages/core/tools/src/index.ts:682" + "packages/core/tools/src/index.ts:689" ] }, { @@ -29037,9 +36007,7 @@ } ] }, - "names": [ - "event:compaction/start.data" - ], + "names": [], "sources": [ "packages/compaction/compaction/src/types.ts:24" ] @@ -29114,9 +36082,2774 @@ } ] }, - "names": [ - "event:feedback/message-delete" - ], + "names": [], + "sources": [] + }, + { + "digest": "3f72db3d87a0c5c43e68be467b4cca728eaf5adc1d5d2b6975ff42bfbd961761", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 25, + "optional": true + }, + { + "name": "seq", + "type": 18, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 193, + "optional": true + }, + { + "name": "surfaceOp", + "type": 194, + "optional": false + }, + { + "name": "time", + "type": 18, + "optional": false + }, + { + "name": "type", + "type": 197, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 32, + 35, + 37, + 39, + 41, + 43, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 61, + 62, + 63, + 64, + 65, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 109, + 111, + 114, + 115, + 116, + 117, + 118, + 120, + 121, + 122, + 123, + 125, + 126, + 127, + 128, + 129, + 131, + 132, + 133, + 135, + 136, + 144, + 146, + 147, + 149, + 151, + 155, + 157, + 165, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 183, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 108, + "optional": false + }, + { + "name": "revision", + "type": 18, + "optional": false + }, + { + "name": "round", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 110, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 112, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 113, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 119, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 124, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 130, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 25, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 137, + "optional": false + }, + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 143, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 138 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 139, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 140, + 141, + 142 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 145, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 152, + "optional": false + }, + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 154, + "optional": false + }, + { + "name": "update", + "type": 25, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 153 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 44, + "optional": false + }, + { + "name": "kind", + "type": 156, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 158, + "optional": false + }, + { + "name": "references", + "type": 159, + "optional": false + }, + { + "name": "version", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 160 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 18, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 161, + "optional": false + }, + { + "name": "compacted", + "type": 163, + "optional": false + }, + { + "name": "inputIndex", + "type": 18, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 18, + "optional": false + }, + { + "name": "omittedMessages", + "type": 18, + "optional": false + }, + { + "name": "originalMessages", + "type": 18, + "optional": false + }, + { + "name": "retainedMessages", + "type": 18, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 162 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 168 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 182, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 184, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 18 + }, + { + "kind": "union", + "types": [ + 195, + 196 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 18, + "optional": false + }, + { + "name": "op", + "type": 141, + "optional": false + }, + { + "name": "startSeq", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user/message" + } + ] + }, + "names": [], "sources": [] }, { @@ -29133,6 +38866,2644 @@ "names": [], "sources": [] }, + { + "digest": "408927267422a7b2beb6df354ff7c1406d929a5646554f48adf85eb8372f811c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "plan-mode" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "40e314bd88730b4bff04a2083cc540ef8659ee2240eeaae0132cac974784b945", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 4, + 6, + 8, + 10, + 12, + 14, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 53, + 55, + 58, + 59, + 60, + 62, + 63, + 64, + 65, + 67, + 68, + 69, + 70, + 71, + 73, + 75, + 76, + 78, + 79, + 80, + 81, + 91, + 93, + 94, + 96, + 99, + 103, + 105, + 113, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 131, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "revision", + "type": 52, + "optional": false + }, + { + "name": "round", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "messageId", + "type": 50, + "optional": false + }, + { + "name": "senderId", + "type": 50, + "optional": false + }, + { + "name": "senderName", + "type": 50, + "optional": false + }, + { + "name": "teamId", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "model", + "type": 50, + "optional": false + }, + { + "name": "provider", + "type": 50, + "optional": false + }, + { + "name": "replayState", + "type": 57, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 72, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 74, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 77, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 82, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 50, + "optional": true + }, + { + "name": "changes", + "type": 83, + "optional": false + }, + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 90, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "array", + "element": 84 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 85, + "optional": false + }, + { + "name": "digest", + "type": 50, + "optional": true + }, + { + "name": "path", + "type": 50, + "optional": false + }, + { + "name": "scope", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 86, + 87, + 88 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 92, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 50, + "optional": true + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "rpcId", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 50, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 50, + "optional": false + }, + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 98, + "optional": false + }, + { + "name": "provider", + "type": 50, + "optional": false + }, + { + "name": "ruleId", + "type": 50, + "optional": false + }, + { + "name": "source", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 100, + "optional": false + }, + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + }, + { + "name": "update", + "type": 82, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 101 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 50, + "optional": false + }, + { + "name": "name", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + }, + { + "name": "name", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 106, + "optional": false + }, + { + "name": "references", + "type": 107, + "optional": false + }, + { + "name": "version", + "type": 112, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 108 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 52, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 109, + "optional": false + }, + { + "name": "compacted", + "type": 111, + "optional": false + }, + { + "name": "inputIndex", + "type": 52, + "optional": false + }, + { + "name": "label", + "type": 50, + "optional": false + }, + { + "name": "omittedBytes", + "type": 52, + "optional": false + }, + { + "name": "omittedMessages", + "type": 52, + "optional": false + }, + { + "name": "originalMessages", + "type": 52, + "optional": false + }, + { + "name": "retainedMessages", + "type": 52, + "optional": false + }, + { + "name": "sessionId", + "type": 50, + "optional": false + }, + { + "name": "truncated", + "type": 111, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 52, + 110 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 116 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 50, + "optional": false + }, + { + "name": "text", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 20, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 22, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 24, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 26, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 7, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 114, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + }, + { + "name": "sections", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 130, + "optional": false + }, + { + "name": "senderSessionId", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 15, + "optional": false + }, + { + "name": "kind", + "type": 132, + "optional": false + }, + { + "name": "senderSessionId", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 20, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 22, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 24, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 26, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 97, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + }, + { + "name": "summary", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#MessageSource" + ], + "sources": [ + "packages/llm/llm/src/message.ts:136" + ] + }, + { + "digest": "4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 6, + "optional": false + }, + { + "name": "time", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "header", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 14, + "optional": false + }, + { + "name": "startsSeries", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 3, + "optional": true + }, + { + "name": "config", + "type": 5, + "optional": false + }, + { + "name": "system", + "type": 9, + "optional": true + }, + { + "name": "tools", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 6, + "optional": true + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 7, + "optional": true + }, + { + "name": "stop", + "type": 8, + "optional": true + }, + { + "name": "temperature", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "array", + "element": 11 + }, + { + "kind": "object", + "properties": [ + { + "name": "deferLoading", + "type": 4, + "optional": true + }, + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "parameters", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 7, + "value": 13 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "union", + "types": [ + 15, + 16, + 17, + 18 + ] + }, + { + "kind": "literal", + "value": "initial" + }, + { + "kind": "literal", + "value": "resume" + }, + { + "kind": "literal", + "value": "series" + }, + { + "kind": "literal", + "value": "change" + }, + { + "kind": "literal", + "value": "request/header" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f", "schema": { @@ -29223,9 +41594,7 @@ } ] }, - "names": [ - "event:tool-workflow/run-end" - ], + "names": [], "sources": [] }, { @@ -29243,7 +41612,7 @@ "sources": [] }, { - "digest": "443371ec07a03a82a0e93d93abca3e70b03bca55ba5b01d507030fcb66e8fbb4", + "digest": "43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8", "schema": { "root": 0, "nodes": [ @@ -29251,378 +41620,34 @@ "kind": "object", "properties": [ { - "name": "data", + "name": "toolName", "type": 1, "optional": false }, - { - "name": "ignorable", - "type": 24, - "optional": true - }, - { - "name": "seq", - "type": 17, - "optional": false - }, - { - "name": "time", - "type": 17, - "optional": false - }, { "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "message", "type": 2, "optional": false - }, - { - "name": "teamId", - "type": 7, - "optional": false - }, - { - "name": "version", - "type": 29, - "optional": false } ], "indices": [] }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "senderId", - "type": 7, - "optional": false - }, - { - "name": "senderName", - "type": 7, - "optional": false - }, - { - "name": "targetId", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 5, - 9, - 11, - 13, - 15, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 6, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, { "kind": "primitive", "type": "string" }, { "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 7, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 16, - "optional": false - }, - { - "name": "offloaded", - "type": 24, - "optional": true - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 17, - "optional": false - }, - { - "name": "height", - "type": 17, - "optional": false - }, - { - "name": "mediaType", - "type": 18, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": true - }, - { - "name": "originalDimensions", - "type": 23, - "optional": true - }, - { - "name": "width", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 19, - 20, - 21, - 22 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 17, - "optional": false - }, - { - "name": "width", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 27, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "literal", - "value": 2 - }, - { - "kind": "literal", - "value": "team/message/queued" + "value": "tool-removal" } ] }, "names": [ - "event:team/message/queued" + "packages/llm/llm/src/types.ts#ToolRemovalBlock" ], - "sources": [] + "sources": [ + "packages/llm/llm/src/types.ts:127" + ] }, { "digest": "44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e", @@ -29718,9 +41743,7 @@ } ] }, - "names": [ - "event:step/start" - ], + "names": [], "sources": [] }, { @@ -29760,9 +41783,7 @@ } ] }, - "names": [ - "event:approval/asked.data" - ], + "names": [], "sources": [ "packages/interaction/user-approval/src/types.ts:44" ] @@ -29813,84 +41834,68 @@ } ] }, - "names": [ - "event:image/offload.data" - ], + "names": [], "sources": [ "packages/compaction/compaction-image-offload/src/projection.ts:25" ] }, { - "digest": "478738df7e7d2b103b09fb937817a9302c81076809f2b341169e00a9419c5665", + "digest": "47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b", "schema": { "root": 0, "nodes": [ { - "kind": "array", - "element": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "role", - "type": 28, - "optional": false - }, - { - "name": "source", - "type": 32, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, + "kind": "literal", + "value": "session-log-deepseek/delivery-accepted" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "47e9095591ae36e7c39ee62553097772f2bfa16304536a72dbbc3f691f605180", + "schema": { + "root": 0, + "nodes": [ { "kind": "union", "types": [ - 4, - 7, - 18, - 21, - 24, - 26 + 1, + 5, + 32, + 35, + 37, + 39, + 56 ] }, { "kind": "object", "properties": [ { - "name": "arguments", - "type": 5, + "name": "argumentsDelta", + "type": 2, "optional": false }, { "name": "id", - "type": 5, + "type": 2, + "optional": false + }, + { + "name": "index", + "type": 3, "optional": false }, { "name": "name", - "type": 5, - "optional": false + "type": 2, + "optional": true }, { "name": "type", - "type": 6, + "type": 4, "optional": false } ], @@ -29900,6 +41905,73 @@ "kind": "primitive", "type": "string" }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 7, + 9, + 19, + 22, + 24, + 26, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", "value": "tool-call" @@ -29909,17 +41981,17 @@ "properties": [ { "name": "attachment", - "type": 8, + "type": 10, "optional": false }, { "name": "offloaded", - "type": 16, + "type": 17, "optional": true }, { "name": "type", - "type": 17, + "type": 18, "optional": false } ], @@ -29930,53 +42002,49 @@ "properties": [ { "name": "attachmentId", - "type": 5, + "type": 2, "optional": false }, { "name": "bytes", - "type": 9, + "type": 3, "optional": false }, { "name": "height", - "type": 9, + "type": 3, "optional": false }, { "name": "mediaType", - "type": 10, + "type": 11, "optional": false }, { "name": "name", - "type": 5, + "type": 2, "optional": true }, { "name": "originalDimensions", - "type": 15, + "type": 16, "optional": true }, { "name": "width", - "type": 9, + "type": 3, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "number" - }, { "kind": "union", "types": [ - 11, 12, 13, - 14 + 14, + 15 ] }, { @@ -30000,12 +42068,12 @@ "properties": [ { "name": "height", - "type": 9, + "type": 3, "optional": false }, { "name": "width", - "type": 9, + "type": 3, "optional": false } ], @@ -30024,12 +42092,12 @@ "properties": [ { "name": "attachment", - "type": 19, + "type": 20, "optional": false }, { "name": "type", - "type": 20, + "type": 21, "optional": false } ], @@ -30040,17 +42108,17 @@ "properties": [ { "name": "attachmentId", - "type": 5, + "type": 2, "optional": false }, { "name": "bytes", - "type": 9, + "type": 3, "optional": false }, { "name": "name", - "type": 5, + "type": 2, "optional": false } ], @@ -30064,20 +42132,10 @@ "kind": "object", "properties": [ { - "name": "content", + "name": "text", "type": 2, "optional": false }, - { - "name": "isError", - "type": 22, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, { "name": "type", "type": 23, @@ -30086,30 +42144,6 @@ ], "indices": [] }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", "value": "reasoning" @@ -30119,12 +42153,12 @@ "properties": [ { "name": "text", - "type": 5, + "type": 2, "optional": false }, { "name": "type", - "type": 27, + "type": 25, "optional": false } ], @@ -30135,106 +42169,161 @@ "value": "text" }, { - "kind": "union", - "types": [ - 29, - 30, - 31 - ] + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" }, { "kind": "literal", - "value": "system" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 33, - 42, - 44, - 45, - 48, - 53, - 55, - 60, - 61, - 62, - 64, - 66, - 67, - 74, - 76, - 78, - 80, - 82, - 85, - 86 - ] + "value": "tool-addition" }, { "kind": "object", "properties": [ { - "name": "baseline", - "type": 16, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 5, - "optional": true - }, - { - "name": "changes", - "type": 34, + "name": "toolName", + "type": 2, "optional": false }, { - "name": "form", + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 33, + "optional": false + }, + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 18, + 21, + 23, + 25, + 28, + 30 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 3, + "optional": false + }, + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", "type": 40, "optional": false }, { - "name": "kind", - "type": 41, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 35 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 36, - "optional": false - }, - { - "name": "digest", - "type": 5, + "name": "replayState", + "type": 52, "optional": true }, { - "name": "path", - "type": 5, - "optional": false - }, - { - "name": "scope", - "type": 5, + "name": "type", + "type": 55, "optional": false } ], @@ -30243,37 +42332,19 @@ { "kind": "union", "types": [ - 37, - 38, - 39 + 41, + 44, + 46, + 48, + 50 ] }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, { "kind": "object", "properties": [ { - "name": "callId", - "type": 5, + "name": "failure", + "type": 42, "optional": false }, { @@ -30284,67 +42355,87 @@ ], "indices": [] }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 2, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, { "kind": "literal", - "value": "tool" + "value": "aborted" }, { "kind": "object", "properties": [ { - "name": "clientTimeZone", - "type": 5, - "optional": true - }, - { - "name": "kind", - "type": 31, + "name": "failure", + "type": 42, "optional": false }, { - "name": "rpcId", - "type": 5, + "name": "kind", + "type": 45, "optional": false } ], "indices": [] }, + { + "kind": "literal", + "value": "error" + }, { "kind": "object", "properties": [ - { - "name": "deliveryId", - "type": 5, - "optional": false - }, - { - "name": "form", - "type": 46, - "optional": false - }, { "name": "kind", "type": 47, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "ruleId", - "type": 5, - "optional": false - }, - { - "name": "source", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, + "name": "kind", + "type": 49, "optional": false } ], @@ -30352,111 +42443,61 @@ }, { "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" + "value": "stop" }, { "kind": "object", "properties": [ { - "name": "entries", - "type": 49, - "optional": false - }, - { - "name": "form", + "name": "kind", "type": 51, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ { - "name": "kind", - "type": 52, - "optional": false - }, - { - "name": "update", - "type": 16, + "name": "blocks", + "type": 53, "optional": true + }, + { + "name": "response", + "type": 54, + "optional": false } ], "indices": [] }, { "kind": "array", - "element": 50 + "element": 54 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" }, { "kind": "object", "properties": [ { - "name": "description", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 40, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 56, - "optional": false - }, - { - "name": "kind", + "name": "type", "type": 57, "optional": false }, { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "sections", + "name": "usage", "type": 58, "optional": false } @@ -30465,281 +42506,495 @@ }, { "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 59 + "value": "usage" }, { "kind": "object", "properties": [ { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "text", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 46, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 40, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 63, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 65, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 51, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - }, - { - "name": "plugin", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 63, - "optional": false - }, - { - "name": "kind", - "type": 68, - "optional": false - }, - { - "name": "references", - "type": 69, - "optional": false - }, - { - "name": "version", - "type": 73, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 70 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 9, + "name": "cacheReadTokens", + "type": 3, "optional": true }, { - "name": "capturedThroughSeq", - "type": 71, + "name": "cacheWriteTokens", + "type": 3, + "optional": true + }, + { + "name": "inputTokens", + "type": 3, "optional": false }, { - "name": "compacted", - "type": 22, + "name": "outputTokens", + "type": 3, "optional": false }, { - "name": "inputIndex", - "type": 9, + "name": "reasoningTokens", + "type": 3, + "optional": true + }, + { + "name": "totalTokens", + "type": 3, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#StreamChunk" + ], + "sources": [ + "packages/llm/llm/src/types.ts:440" + ] + }, + { + "digest": "487b65c37bfedb8b72088c4107a0a90a6249701f6b26745f6d98f9b8a22b07c7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 1, "optional": false }, { - "name": "label", + "name": "time", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 6, + 33, + 36, + 38, + 40, + 57 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "type", "type": 5, "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 7, + "optional": false }, { - "name": "omittedBytes", + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 8, + 10, + 20, + 23, + 25, + 27, + 30 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", "type": 9, "optional": false - }, + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ { - "name": "omittedMessages", - "type": 9, + "name": "attachment", + "type": 11, "optional": false }, { - "name": "originalMessages", - "type": 9, + "name": "offloaded", + "type": 18, + "optional": true + }, + { + "name": "type", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, "optional": false }, { - "name": "retainedMessages", - "type": 9, + "name": "bytes", + "type": 4, "optional": false }, { - "name": "sessionId", - "type": 5, + "name": "height", + "type": 4, "optional": false }, { - "name": "truncated", + "name": "mediaType", + "type": 12, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 17, + "optional": true + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 13, + 14, + 15, + 16 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 21, + "optional": false + }, + { + "name": "type", "type": 22, "optional": false } ], "indices": [] }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 28, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 34, + "optional": false + }, + { + "name": "index", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 35, + "optional": false + } + ], + "indices": [] + }, { "kind": "union", "types": [ 9, - 72 + 19, + 22, + 24, + 26, + 29, + 31 ] }, - { - "kind": "primitive", - "type": "null" - }, { "kind": "literal", - "value": 1 + "value": "block-start" }, { "kind": "object", "properties": [ { - "name": "form", - "type": 46, + "name": "index", + "type": 4, "optional": false }, { - "name": "kind", - "type": 75, + "name": "text", + "type": 3, "optional": false }, { - "name": "senderSessionId", - "type": 5, - "optional": false - }, - { - "name": "summary", - "type": 5, + "name": "type", + "type": 37, "optional": false } ], @@ -30747,24 +43002,24 @@ }, { "kind": "literal", - "value": "subagent-settled" + "value": "reasoning-delta" }, { "kind": "object", "properties": [ { - "name": "form", - "type": 65, + "name": "index", + "type": 4, "optional": false }, { - "name": "kind", - "type": 77, + "name": "text", + "type": 3, "optional": false }, { - "name": "senderSessionId", - "type": 5, + "name": "type", + "type": 39, "optional": false } ], @@ -30772,94 +43027,86 @@ }, { "kind": "literal", - "value": "agent-message" + "value": "text-delta" }, { "kind": "object", "properties": [ { - "name": "goalId", - "type": 5, - "optional": false - }, - { - "name": "kind", - "type": 79, - "optional": false - }, - { - "name": "revision", - "type": 9, - "optional": false - }, - { - "name": "round", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 81, - "optional": false - }, - { - "name": "messageId", - "type": 5, - "optional": false - }, - { - "name": "senderId", - "type": 5, - "optional": false - }, - { - "name": "senderName", - "type": 5, - "optional": false - }, - { - "name": "teamId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 83, - "optional": false - }, - { - "name": "model", - "type": 5, - "optional": false - }, - { - "name": "provider", - "type": 5, + "name": "reason", + "type": 41, "optional": false }, { "name": "replayState", - "type": 84, + "type": 53, + "optional": true + }, + { + "name": "type", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 42, + 45, + 47, + 49, + 51 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "offloadImages", + "type": 4, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 4, + "optional": true + }, + { + "name": "requestId", + "type": 3, + "optional": true + }, + { + "name": "status", + "type": 4, "optional": true } ], @@ -30867,59 +43114,167 @@ }, { "kind": "literal", - "value": "model" + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 54, + "optional": true + }, + { + "name": "response", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 55 }, { "kind": "opaque", "reason": "unknown" }, + { + "kind": "literal", + "value": "finish" + }, { "kind": "object", "properties": [ { - "name": "kind", - "type": 57, + "name": "type", + "type": 58, "optional": false }, { - "name": "plugin", - "type": 5, + "name": "usage", + "type": 59, "optional": false } ], "indices": [] }, + { + "kind": "literal", + "value": "usage" + }, { "kind": "object", "properties": [ { - "name": "kind", - "type": 31, + "name": "cacheReadTokens", + "type": 4, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 4, + "optional": true + }, + { + "name": "inputTokens", + "type": 4, "optional": false + }, + { + "name": "outputTokens", + "type": 4, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 4, + "optional": true + }, + { + "name": "totalTokens", + "type": 4, + "optional": true } ], "indices": [] - } - ] - }, - "names": [ - "event:session/title-llm-request.data.messages" - ], - "sources": [] - }, - { - "digest": "47e5d84f1a93450a78c7f3954b43990d0f629af7c034a56313e5deb63e772c1b", - "schema": { - "root": 0, - "nodes": [ + }, { "kind": "literal", - "value": "session-log-deepseek/delivery-accepted" + "value": "chunk" } ] }, "names": [], - "sources": [] + "sources": [ + "packages/llm/llm/src/assistant-stream.ts:44" + ] }, { "digest": "48e5c9861f16ac07e78cb7b5ae9dabdf7bb85c58baed5a51b4ad275050ea58e3", @@ -31001,9 +43356,7 @@ } ] }, - "names": [ - "event:llm/retry-started" - ], + "names": [], "sources": [] }, { @@ -31090,9 +43443,104 @@ } ] }, - "names": [ - "event:team/message/delivered" - ], + "names": [], + "sources": [] + }, + { + "digest": "4991dfc415c9efebc36fa6969e1798c7d2e42396cc1e6e0ac7d7c89c5c5c4aea", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "49dab019d00e8c26f27ad2ccff7b604d69e323ae4d17e0d2a7b6b8a830b1ade2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], "sources": [] }, { @@ -31206,11 +43654,378 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request.data.body.tools" - ], + "names": [], "sources": [] }, + { + "digest": "4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "isError", + "type": 29, + "optional": true + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + }, + { + "name": "toolCallId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 8, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 9, + "optional": true + }, + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#ToolResultMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts:173" + ] + }, { "digest": "4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea", "schema": { @@ -31262,9 +44077,7 @@ } ] }, - "names": [ - "event:todo/write.data.todos" - ], + "names": [], "sources": [] }, { @@ -31289,791 +44102,9 @@ } ] }, - "names": [ - "event:turn/end.data.reason[1].reason[3]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:192" - ] - }, - { - "digest": "4c965666d5b42116945bc356087cd5e1fd549e6dece560785ed60511059a8283", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "union", - "types": [ - 1, - 12, - 14, - 16, - 19, - 24, - 26, - 31, - 32, - 34, - 35, - 36, - 38, - 47, - 49, - 51, - 53, - 55, - 58, - 59 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 2, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 3, - "optional": true - }, - { - "name": "changes", - "type": 4, - "optional": false - }, - { - "name": "form", - "type": 10, - "optional": false - }, - { - "name": "kind", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 5 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 6, - "optional": false - }, - { - "name": "digest", - "type": 3, - "optional": true - }, - { - "name": "path", - "type": 3, - "optional": false - }, - { - "name": "scope", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 7, - 8, - 9 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 3, - "optional": false - }, - { - "name": "kind", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 3, - "optional": true - }, - { - "name": "kind", - "type": 15, - "optional": false - }, - { - "name": "rpcId", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 3, - "optional": false - }, - { - "name": "form", - "type": 17, - "optional": false - }, - { - "name": "kind", - "type": 18, - "optional": false - }, - { - "name": "provider", - "type": 3, - "optional": false - }, - { - "name": "ruleId", - "type": 3, - "optional": false - }, - { - "name": "source", - "type": 3, - "optional": false - }, - { - "name": "summary", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 20, - "optional": false - }, - { - "name": "form", - "type": 22, - "optional": false - }, - { - "name": "kind", - "type": 23, - "optional": false - }, - { - "name": "update", - "type": 2, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 21 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 10, - "optional": false - }, - { - "name": "kind", - "type": 25, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 27, - "optional": false - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - }, - { - "name": "sections", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 30 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 3, - "optional": false - }, - { - "name": "text", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 17, - "optional": false - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - }, - { - "name": "summary", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 33, - "optional": false - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 22, - "optional": false - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 10, - "optional": false - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 39, - "optional": false - }, - { - "name": "references", - "type": 40, - "optional": false - }, - { - "name": "version", - "type": 46, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 41 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 42, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 43, - "optional": false - }, - { - "name": "compacted", - "type": 45, - "optional": false - }, - { - "name": "inputIndex", - "type": 42, - "optional": false - }, - { - "name": "label", - "type": 3, - "optional": false - }, - { - "name": "omittedBytes", - "type": 42, - "optional": false - }, - { - "name": "omittedMessages", - "type": 42, - "optional": false - }, - { - "name": "originalMessages", - "type": 42, - "optional": false - }, - { - "name": "retainedMessages", - "type": 42, - "optional": false - }, - { - "name": "sessionId", - "type": 3, - "optional": false - }, - { - "name": "truncated", - "type": 45, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 42, - 44 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 17, - "optional": false - }, - { - "name": "kind", - "type": 48, - "optional": false - }, - { - "name": "senderSessionId", - "type": 3, - "optional": false - }, - { - "name": "summary", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 33, - "optional": false - }, - { - "name": "kind", - "type": 50, - "optional": false - }, - { - "name": "senderSessionId", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 3, - "optional": false - }, - { - "name": "kind", - "type": 52, - "optional": false - }, - { - "name": "revision", - "type": 42, - "optional": false - }, - { - "name": "round", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "messageId", - "type": 3, - "optional": false - }, - { - "name": "senderId", - "type": 3, - "optional": false - }, - { - "name": "senderName", - "type": 3, - "optional": false - }, - { - "name": "teamId", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "model", - "type": 3, - "optional": false - }, - { - "name": "provider", - "type": 3, - "optional": false - }, - { - "name": "replayState", - "type": 57, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 15, - "optional": false - } - ], - "indices": [] - } - ] - }, - "names": [ - "packages/llm/llm/src/message.ts#MessageSource" - ], - "sources": [ - "packages/llm/llm/src/message.ts:128" + "packages/core/session/src/types.ts:193" ] }, { @@ -32113,10 +44144,10 @@ "packages/workflow/workflow/src/types.ts#WorkflowRunId" ], "sources": [ - "packages/api/session-controller/src/types.ts:376", + "packages/api/session-controller/src/types.ts:380", "packages/attachment/attachment/src/brand.ts:6", "packages/compaction/compaction/src/brand.ts:4", - "packages/core/session/src/types.ts:19", + "packages/core/session/src/types.ts:20", "packages/experimental/agent-team/src/types.ts:20", "packages/experimental/agent-team/src/types.ts:32", "packages/experimental/agent-team/src/types.ts:8", @@ -32138,1075 +44169,6 @@ "packages/workflow/workflow/src/types.ts:13" ] }, - { - "digest": "4de5e7644130ed715ef6b5a4d86a87b30dca4096d1a6683c66acf6f7809379c7", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "role", - "type": 27, - "optional": false - }, - { - "name": "source", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "union", - "types": [ - 3, - 6, - 17, - 20, - 23, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 7, - "optional": false - }, - { - "name": "offloaded", - "type": 15, - "optional": true - }, - { - "name": "type", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 8, - "optional": false - }, - { - "name": "height", - "type": 8, - "optional": false - }, - { - "name": "mediaType", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "originalDimensions", - "type": 14, - "optional": true - }, - { - "name": "width", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 10, - 11, - 12, - 13 - ] - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 8, - "optional": false - }, - { - "name": "width", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 18, - "optional": false - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 8, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "isError", - "type": 21, - "optional": true - }, - { - "name": "toolCallId", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 29, - 38, - 40, - 41, - 44, - 49, - 51, - 56, - 57, - 58, - 60, - 62, - 63, - 70, - 72, - 74, - 76, - 78, - 81, - 82 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 15, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 4, - "optional": true - }, - { - "name": "changes", - "type": 30, - "optional": false - }, - { - "name": "form", - "type": 36, - "optional": false - }, - { - "name": "kind", - "type": 37, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 31 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 32, - "optional": false - }, - { - "name": "digest", - "type": 4, - "optional": true - }, - { - "name": "path", - "type": 4, - "optional": false - }, - { - "name": "scope", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 33, - 34, - 35 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 4, - "optional": false - }, - { - "name": "kind", - "type": 39, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 4, - "optional": true - }, - { - "name": "kind", - "type": 27, - "optional": false - }, - { - "name": "rpcId", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 4, - "optional": false - }, - { - "name": "form", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 43, - "optional": false - }, - { - "name": "provider", - "type": 4, - "optional": false - }, - { - "name": "ruleId", - "type": 4, - "optional": false - }, - { - "name": "source", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 45, - "optional": false - }, - { - "name": "form", - "type": 47, - "optional": false - }, - { - "name": "kind", - "type": 48, - "optional": false - }, - { - "name": "update", - "type": 15, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 46 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 36, - "optional": false - }, - { - "name": "kind", - "type": 50, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 52, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "sections", - "type": 54, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 55 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "text", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 36, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 59, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 61, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 47, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 59, - "optional": false - }, - { - "name": "kind", - "type": 64, - "optional": false - }, - { - "name": "references", - "type": 65, - "optional": false - }, - { - "name": "version", - "type": 69, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 66 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 8, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 67, - "optional": false - }, - { - "name": "compacted", - "type": 21, - "optional": false - }, - { - "name": "inputIndex", - "type": 8, - "optional": false - }, - { - "name": "label", - "type": 4, - "optional": false - }, - { - "name": "omittedBytes", - "type": 8, - "optional": false - }, - { - "name": "omittedMessages", - "type": 8, - "optional": false - }, - { - "name": "originalMessages", - "type": 8, - "optional": false - }, - { - "name": "retainedMessages", - "type": 8, - "optional": false - }, - { - "name": "sessionId", - "type": 4, - "optional": false - }, - { - "name": "truncated", - "type": 21, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 8, - 68 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 71, - "optional": false - }, - { - "name": "senderSessionId", - "type": 4, - "optional": false - }, - { - "name": "summary", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 61, - "optional": false - }, - { - "name": "kind", - "type": 73, - "optional": false - }, - { - "name": "senderSessionId", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 4, - "optional": false - }, - { - "name": "kind", - "type": 75, - "optional": false - }, - { - "name": "revision", - "type": 8, - "optional": false - }, - { - "name": "round", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 77, - "optional": false - }, - { - "name": "messageId", - "type": 4, - "optional": false - }, - { - "name": "senderId", - "type": 4, - "optional": false - }, - { - "name": "senderName", - "type": 4, - "optional": false - }, - { - "name": "teamId", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 79, - "optional": false - }, - { - "name": "model", - "type": 4, - "optional": false - }, - { - "name": "provider", - "type": 4, - "optional": false - }, - { - "name": "replayState", - "type": 80, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "plugin", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 27, - "optional": false - } - ], - "indices": [] - } - ] - }, - "names": [ - "packages/llm/llm/src/message.ts#UserMessage" - ], - "sources": [ - "packages/llm/llm/src/message.ts:143" - ] - }, { "digest": "4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159", "schema": { @@ -33267,11 +44229,10 @@ ] }, "names": [ - "event:web/deepseek-search-llm-request.data.body.messages[0].content[0]", "packages/llm/llm/src/types.ts#TextBlock" ], "sources": [ - "packages/llm/llm/src/types.ts:61", + "packages/llm/llm/src/types.ts:62", "packages/web/web-search-deepseek/src/provider.ts:66" ] }, @@ -33327,6 +44288,20 @@ "packages/subagent/subagent/src/continuation-messages.ts:30" ] }, + { + "digest": "4edec1b770e8ec4ce1220bf42edc5ac46713a1b48d4caa778dcfc98bad1f28a3", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "ptc-mode" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f", "schema": { @@ -33432,9 +44407,7 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[15].references[0]" - ], + "names": [], "sources": [ "packages/context/session-reference/src/types.ts:18" ] @@ -33594,9 +44567,7 @@ } ] }, - "names": [ - "event:team/member" - ], + "names": [], "sources": [] }, { @@ -33621,9 +44592,7 @@ } ] }, - "names": [ - "event:team/member.data.member.context" - ], + "names": [], "sources": [] }, { @@ -33730,11 +44699,2727 @@ } ] }, - "names": [ - "event:sandbox/mode" - ], + "names": [], "sources": [] }, + { + "digest": "51c78ccc9023ce6642d07fb9a10cbf942ff7e313d5b304ddc77218df71da708f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "headerSeq", + "type": 1, + "optional": true + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 13, + 15, + 17, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 32, + 35, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 61, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 105, + 107, + 110, + 111, + 112, + 113, + 114, + 116, + 117, + 118, + 119, + 121, + 122, + 123, + 124, + 125, + 127, + 129, + 131, + 132, + 133, + 141, + 143, + 144, + 146, + 148, + 152, + 154, + 162, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 180, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + }, + { + "name": "revision", + "type": 1, + "optional": false + }, + { + "name": "round", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 106, + "optional": false + }, + { + "name": "messageId", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 108, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "replayState", + "type": 109, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 115, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 120, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 126, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 128, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 130, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 25, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 6, + "optional": true + }, + { + "name": "changes", + "type": 134, + "optional": false + }, + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 140, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 135 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 136, + "optional": false + }, + { + "name": "digest", + "type": 6, + "optional": true + }, + { + "name": "path", + "type": 6, + "optional": false + }, + { + "name": "scope", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 137, + 138, + 139 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 142, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 6, + "optional": true + }, + { + "name": "kind", + "type": 128, + "optional": false + }, + { + "name": "rpcId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 145, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 6, + "optional": false + }, + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 147, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "ruleId", + "type": 6, + "optional": false + }, + { + "name": "source", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 149, + "optional": false + }, + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "update", + "type": 25, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 150 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 155, + "optional": false + }, + { + "name": "references", + "type": 156, + "optional": false + }, + { + "name": "version", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 157 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 1, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 158, + "optional": false + }, + { + "name": "compacted", + "type": 160, + "optional": false + }, + { + "name": "inputIndex", + "type": 1, + "optional": false + }, + { + "name": "label", + "type": 6, + "optional": false + }, + { + "name": "omittedBytes", + "type": 1, + "optional": false + }, + { + "name": "omittedMessages", + "type": 1, + "optional": false + }, + { + "name": "originalMessages", + "type": 1, + "optional": false + }, + { + "name": "retainedMessages", + "type": 1, + "optional": false + }, + { + "name": "sessionId", + "type": 6, + "optional": false + }, + { + "name": "truncated", + "type": 160, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 1, + 159 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 165 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 163, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "sections", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 179, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 181, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:311" + ] + }, { "digest": "51edec100659da3a9bd9c3f6ba1180f5e64ec9a1585e5057080df45c180bd357", "schema": { @@ -34044,9 +47729,7 @@ } ] }, - "names": [ - "event:llm/retry" - ], + "names": [], "sources": [] }, { @@ -34097,14 +47780,522 @@ } ] }, - "names": [ - "event:tool/result.data.meta[5][0][6]", - "event:tool/result.data.meta[6]" - ], + "names": [], "sources": [ "packages/util/values/src/index.ts:4" ] }, + { + "digest": "52c6113cb0e53f345324bf84f01928bea5d5df57ee80bc0dd65407b8bc5a3734", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5302e763151277614b97e77f00e3b326694c6c1247b916a20503c344dc970777", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 1, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "meta", + "type": 34, + "optional": true + }, + { + "name": "step", + "type": 19, + "optional": false + }, + { + "name": "turn", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "reason", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "isError", + "type": 31, + "optional": true + }, + { + "name": "role", + "type": 32, + "optional": false + }, + { + "name": "source", + "type": 33, + "optional": false + }, + { + "name": "toolCallId", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 8, + 10, + 13, + 15, + 17, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 2, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 19, + 31, + 35, + 36, + 37 + ] + }, + { + "kind": "array", + "element": 34 + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 2, + "value": 34 + } + ] + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:375" + ] + }, { "digest": "530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6", "schema": { @@ -34141,7 +48332,921 @@ "packages/core/session/src/types.ts#RequestHeaderReason" ], "sources": [ - "packages/core/session/src/types.ts:261" + "packages/core/session/src/types.ts:273" + ] + }, + { + "digest": "53cf1704ae0709c7678bcf070c83c619fc48ca1b5c173b74cfa8702f22a8e492", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "tool-jobs" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "54f9276a1617d7c12594722c89cfe864bcbe4517e9a6f9c98bab14f199a135e0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "step", + "type": 1, + "optional": false + }, + { + "name": "stream", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 9, + 68, + 70 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "args", + "type": 5, + "optional": false + }, + { + "name": "dt", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "time0", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 1 + }, + { + "kind": "literal", + "value": "tool-call-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "chunk", + "type": 10, + "optional": false + }, + { + "name": "time", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 67, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 11, + 13, + 40, + 43, + 45, + 47, + 64 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "argumentsDelta", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "block", + "type": 14, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 15, + 17, + 27, + 30, + 32, + 34, + 37 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 35, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "literal", + "value": "block-end" + }, + { + "kind": "object", + "properties": [ + { + "name": "blockType", + "type": 41, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 16, + 26, + 29, + 31, + 33, + 36, + 38 + ] + }, + { + "kind": "literal", + "value": "block-start" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-delta" + }, + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 48, + "optional": false + }, + { + "name": "replayState", + "type": 60, + "optional": true + }, + { + "name": "type", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 49, + 52, + 54, + 56, + 58 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 6, + "optional": false + }, + { + "name": "message", + "type": 6, + "optional": false + }, + { + "name": "offloadImages", + "type": 1, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 1, + "optional": true + }, + { + "name": "requestId", + "type": 6, + "optional": true + }, + { + "name": "status", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 50, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "stop" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-calls" + }, + { + "kind": "object", + "properties": [ + { + "name": "blocks", + "type": 61, + "optional": true + }, + { + "name": "response", + "type": 62, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 62 + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "literal", + "value": "finish" + }, + { + "kind": "object", + "properties": [ + { + "name": "type", + "type": 65, + "optional": false + }, + { + "name": "usage", + "type": 66, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "usage" + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 1, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 1, + "optional": true + }, + { + "name": "inputTokens", + "type": 1, + "optional": false + }, + { + "name": "outputTokens", + "type": 1, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 1, + "optional": true + }, + { + "name": "totalTokens", + "type": 1, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "chunk" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "texts", + "type": 5, + "optional": false + }, + { + "name": "time0", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning-chunks" + }, + { + "kind": "object", + "properties": [ + { + "name": "dt", + "type": 7, + "optional": false + }, + { + "name": "index", + "type": 1, + "optional": false + }, + { + "name": "texts", + "type": 5, + "optional": false + }, + { + "name": "time0", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text-chunks" + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:355" ] }, { @@ -34158,6 +49263,69 @@ "names": [], "sources": [] }, + { + "digest": "5654685d7557ec747e74887237065e626a5bdfa426ca43f7fbb0b6fee9b0916c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23", "schema": { @@ -34180,11 +49348,9 @@ } ] }, - "names": [ - "event:turn/end.data.reason[5]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:220" + "packages/core/session/src/types.ts:221" ] }, { @@ -34201,6 +49367,428 @@ "names": [], "sources": [] }, + { + "digest": "576a2de8355eb09850963ff5953420b172e274d9283666eb7d889097db120796", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 1, + "optional": false + }, + { + "name": "maxTokens", + "type": 2, + "optional": true + }, + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "rawOutput", + "type": 3, + "optional": true + }, + { + "name": "shadowedRange", + "type": 29, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 30, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 2, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 1, + "optional": true + }, + { + "name": "summary", + "type": 3, + "optional": false + }, + { + "name": "usage", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 7, + 9, + 12, + 14, + 16, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 2, + "optional": false + }, + { + "name": "start", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 2, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 2, + "optional": true + }, + { + "name": "inputTokens", + "type": 2, + "optional": false + }, + { + "name": "outputTokens", + "type": 2, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 2, + "optional": true + }, + { + "name": "totalTokens", + "type": 2, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc", "schema": { @@ -34361,9 +49949,7 @@ } ] }, - "names": [ - "SessionEventEnvelope" - ], + "names": [], "sources": [] }, { @@ -34380,6 +49966,40 @@ "names": [], "sources": [] }, + { + "digest": "58015da1c1950a66daf66ae24913d6a1fc6d1d9ac441b155f8847f7f8584ba8e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "runtime-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "5808e36c95355f0e745201b5db1b6bcec4ebf5adb75d3e82d7d59cc89635ab80", "schema": { @@ -34530,7 +50150,7 @@ "packages/llm/llm/src/types.ts#FinishReason" ], "sources": [ - "packages/llm/llm/src/types.ts:152" + "packages/llm/llm/src/types.ts:166" ] }, { @@ -34547,6 +50167,20 @@ "names": [], "sources": [] }, + { + "digest": "589d0d91239681f89ee485459dc8c2f73ea47183b5534289d966637024a2c35d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "developer" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "58f94390b982f8a5ac1f4f235ba612557f4a1dc4a995d8b1cec63ce7639decb0", "schema": { @@ -34589,330 +50223,6 @@ "names": [], "sources": [] }, - { - "digest": "5b694f394d5e11609887a3ccfa82844935d49806c37e336b30be2186d649ab94", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "senderId", - "type": 5, - "optional": false - }, - { - "name": "senderName", - "type": 5, - "optional": false - }, - { - "name": "targetId", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "union", - "types": [ - 3, - 7, - 9, - 11, - 13, - 24 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "isError", - "type": 4, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 14, - "optional": false - }, - { - "name": "offloaded", - "type": 22, - "optional": true - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 15, - "optional": false - }, - { - "name": "height", - "type": 15, - "optional": false - }, - { - "name": "mediaType", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 21, - "optional": true - }, - { - "name": "width", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 17, - 18, - 19, - 20 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 15, - "optional": false - }, - { - "name": "width", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 25, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 15, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - } - ] - }, - "names": [ - "packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot" - ], - "sources": [ - "packages/experimental/agent-team/src/types.ts:106" - ] - }, { "digest": "5b6fb1f226ff56402db08a6aae82af76100b14056271875f69ec526a1ae05d51", "schema": { @@ -34969,13 +50279,88 @@ } ] }, - "names": [ - "event:command/done.data" - ], + "names": [], "sources": [ "packages/interaction/commands/src/types.ts:112" ] }, + { + "digest": "5bb69b88517f6214f2af4d1a6d2b771e271ad3ad695cc9c2c272069ae698c9bc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "5bc66269cfaf614c0ecda8ecb469f23101a7609793fc2b693ac23c4aecdb575e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "schedule" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "5bd310104cfe448e530beb11422d2f791e2e32e8e95fdc528a15f9ca693dae75", "schema": { @@ -35055,9 +50440,41 @@ } ] }, - "names": [ - "event:permission/preset" - ], + "names": [], + "sources": [] + }, + { + "digest": "5cdbf342b7748d152bc987b68f58e565e5bba4b227e076e2d2120d87662e45cd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "user-approval" + } + ] + }, + "names": [], "sources": [] }, { @@ -35075,23 +50492,7 @@ } ] }, - "names": [ - "SessionEventEnvelope[39].sourceEventSeqs", - "SessionEventEnvelope[52].sourceEventSeqs", - "SessionEventEnvelope[55].sourceEventSeqs", - "event:assistant/attempt.data.stream[0][0].dt", - "event:assistant/attempt.data.stream[0][1].dt", - "event:assistant/attempt.data.stream[0][2].dt", - "event:compaction/prune.data.shadowedSeqs", - "event:compaction/summary.data[0].shadowedSeqs", - "event:compaction/summary.data[1].shadowedSeqs", - "event:image/offload.data.targets[0].imageIndexes", - "event:session/title-llm-request.data.messageSeqs", - "event:session/title.data.messageSeqs", - "event:system/message.sourceEventSeqs", - "event:tool/result.sourceEventSeqs", - "event:user/message.sourceEventSeqs" - ], + "names": [], "sources": [] }, { @@ -35162,9 +50563,41 @@ } ] }, - "names": [ - "event:subagent/catalog.data[0]" - ], + "names": [], + "sources": [] + }, + { + "digest": "5d7a64ed6aac5551ebf998dc25e1e7b48a144769913f89702840180e61dc3995", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "time-context" + } + ] + }, + "names": [], "sources": [] }, { @@ -35219,9 +50652,7 @@ } ] }, - "names": [ - "event:compaction/prune.data" - ], + "names": [], "sources": [ "packages/compaction/compaction/src/types.ts:82" ] @@ -35287,9 +50718,7 @@ } ] }, - "names": [ - "event:session/end-seed" - ], + "names": [], "sources": [] }, { @@ -35361,7 +50790,7 @@ "packages/llm/llm/src/types.ts#LlmFailure" ], "sources": [ - "packages/llm/llm/src/types.ts:40" + "packages/llm/llm/src/types.ts:41" ] }, { @@ -35449,9 +50878,7 @@ } ] }, - "names": [ - "event:tool-workflow/agent-start" - ], + "names": [], "sources": [] }, { @@ -35506,6 +50933,40 @@ "packages/subagent/subagent/src/descriptor.ts:61" ] }, + { + "digest": "6085488d223aeffdef51d7ae17655fc26ab22ee13cbed82a50e62e2b6fb5b918", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "tool-goal" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d", "schema": { @@ -35534,6 +50995,31 @@ "names": [], "sources": [] }, + { + "digest": "6292bcbedaa97feaec5b48a03bb8144b581b93309d9d6c905f26da7a6a7a0a4f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379", "schema": { @@ -35576,9 +51062,7 @@ } ] }, - "names": [ - "event:goal/change.data[0].operation" - ], + "names": [], "sources": [] }, { @@ -35595,1240 +51079,6 @@ "names": [], "sources": [] }, - { - "digest": "646c2f1d243d3a78c5bc9305786fb340f5209c48a97e65f2a186cc5195491f3f", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "data", - "type": 1, - "optional": false - }, - { - "name": "ignorable", - "type": 18, - "optional": true - }, - { - "name": "seq", - "type": 11, - "optional": false - }, - { - "name": "time", - "type": 11, - "optional": false - }, - { - "name": "type", - "type": 90, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "inserted", - "type": 2, - "optional": false - }, - { - "name": "outcome", - "type": 86, - "optional": true - }, - { - "name": "removedCount", - "type": 11, - "optional": true - }, - { - "name": "start", - "type": 11, - "optional": false - }, - { - "name": "target", - "type": 87, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "role", - "type": 30, - "optional": false - }, - { - "name": "source", - "type": 31, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 5 - }, - { - "kind": "union", - "types": [ - 6, - 9, - 20, - 23, - 26, - 28 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 7, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 10, - "optional": false - }, - { - "name": "offloaded", - "type": 18, - "optional": true - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 11, - "optional": false - }, - { - "name": "height", - "type": 11, - "optional": false - }, - { - "name": "mediaType", - "type": 12, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": true - }, - { - "name": "originalDimensions", - "type": 17, - "optional": true - }, - { - "name": "width", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 13, - 14, - 15, - 16 - ] - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 11, - "optional": false - }, - { - "name": "width", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 21, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 11, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 32, - 41, - 43, - 44, - 47, - 52, - 54, - 59, - 60, - 61, - 63, - 65, - 66, - 73, - 75, - 77, - 79, - 81, - 84, - 85 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 18, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 7, - "optional": true - }, - { - "name": "changes", - "type": 33, - "optional": false - }, - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 40, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 34 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 35, - "optional": false - }, - { - "name": "digest", - "type": 7, - "optional": true - }, - { - "name": "path", - "type": 7, - "optional": false - }, - { - "name": "scope", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 36, - 37, - 38 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 7, - "optional": false - }, - { - "name": "kind", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 7, - "optional": true - }, - { - "name": "kind", - "type": 30, - "optional": false - }, - { - "name": "rpcId", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 7, - "optional": false - }, - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 46, - "optional": false - }, - { - "name": "provider", - "type": 7, - "optional": false - }, - { - "name": "ruleId", - "type": 7, - "optional": false - }, - { - "name": "source", - "type": 7, - "optional": false - }, - { - "name": "summary", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 48, - "optional": false - }, - { - "name": "form", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - }, - { - "name": "update", - "type": 18, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 49 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 55, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - }, - { - "name": "sections", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 58 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "text", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - }, - { - "name": "summary", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 64, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 62, - "optional": false - }, - { - "name": "kind", - "type": 67, - "optional": false - }, - { - "name": "references", - "type": 68, - "optional": false - }, - { - "name": "version", - "type": 72, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 69 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 11, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 70, - "optional": false - }, - { - "name": "compacted", - "type": 24, - "optional": false - }, - { - "name": "inputIndex", - "type": 11, - "optional": false - }, - { - "name": "label", - "type": 7, - "optional": false - }, - { - "name": "omittedBytes", - "type": 11, - "optional": false - }, - { - "name": "omittedMessages", - "type": 11, - "optional": false - }, - { - "name": "originalMessages", - "type": 11, - "optional": false - }, - { - "name": "retainedMessages", - "type": 11, - "optional": false - }, - { - "name": "sessionId", - "type": 7, - "optional": false - }, - { - "name": "truncated", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 11, - 71 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 74, - "optional": false - }, - { - "name": "senderSessionId", - "type": 7, - "optional": false - }, - { - "name": "summary", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 64, - "optional": false - }, - { - "name": "kind", - "type": 76, - "optional": false - }, - { - "name": "senderSessionId", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 7, - "optional": false - }, - { - "name": "kind", - "type": 78, - "optional": false - }, - { - "name": "revision", - "type": 11, - "optional": false - }, - { - "name": "round", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 80, - "optional": false - }, - { - "name": "messageId", - "type": 7, - "optional": false - }, - { - "name": "senderId", - "type": 7, - "optional": false - }, - { - "name": "senderName", - "type": 7, - "optional": false - }, - { - "name": "teamId", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 82, - "optional": false - }, - { - "name": "model", - "type": 7, - "optional": false - }, - { - "name": "provider", - "type": 7, - "optional": false - }, - { - "name": "replayState", - "type": 83, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "plugin", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "canceled" - }, - { - "kind": "union", - "types": [ - 88, - 89 - ] - }, - { - "kind": "literal", - "value": "next-step" - }, - { - "kind": "literal", - "value": "next-turn" - }, - { - "kind": "literal", - "value": "agent/inbox/spliced" - } - ] - }, - "names": [ - "event:agent/inbox/spliced" - ], - "sources": [] - }, - { - "digest": "647cb2e3aeb58e27d1d4d60011f208bb66dce257e8654193c533b47c4c22c253", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 1, - "optional": false - }, - { - "name": "index", - "type": 8, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 2, - 3, - 4, - 5, - 6, - 7 - ] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "block-start" - } - ] - }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[0]" - ], - "sources": [ - "packages/llm/llm/src/types.ts:427" - ] - }, { "digest": "6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f", "schema": { @@ -36926,6 +51176,2696 @@ "packages/subagent/subagent/src/descriptor.ts:72" ] }, + { + "digest": "64ea5653002834c44f29bea4620e9c42aeb6024ae5b1d58d69f95158006b2586", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 8, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 9, + "optional": true + }, + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 31, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 102, + 104, + 107, + 108, + 109, + 110, + 112, + 113, + 114, + 115, + 117, + 118, + 119, + 120, + 121, + 123, + 124, + 125, + 127, + 128, + 129, + 137, + 139, + 140, + 142, + 145, + 149, + 151, + 159, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 177, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "revision", + "type": 17, + "optional": false + }, + { + "name": "round", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 103, + "optional": false + }, + { + "name": "messageId", + "type": 4, + "optional": false + }, + { + "name": "senderId", + "type": 4, + "optional": false + }, + { + "name": "senderName", + "type": 4, + "optional": false + }, + { + "name": "teamId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 105, + "optional": false + }, + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "replayState", + "type": 106, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 111, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 116, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 122, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 126, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 24, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 4, + "optional": true + }, + { + "name": "changes", + "type": 130, + "optional": false + }, + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 136, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 131 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 132, + "optional": false + }, + { + "name": "digest", + "type": 4, + "optional": true + }, + { + "name": "path", + "type": 4, + "optional": false + }, + { + "name": "scope", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 133, + 134, + 135 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 138, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 4, + "optional": true + }, + { + "name": "kind", + "type": 29, + "optional": false + }, + { + "name": "rpcId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 141, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 4, + "optional": false + }, + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 144, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "ruleId", + "type": 4, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 146, + "optional": false + }, + { + "name": "form", + "type": 87, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + }, + { + "name": "update", + "type": 24, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 147 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 59, + "optional": false + }, + { + "name": "kind", + "type": 152, + "optional": false + }, + { + "name": "references", + "type": 153, + "optional": false + }, + { + "name": "version", + "type": 158, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 154 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 17, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 155, + "optional": false + }, + { + "name": "compacted", + "type": 157, + "optional": false + }, + { + "name": "inputIndex", + "type": 17, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": false + }, + { + "name": "omittedBytes", + "type": 17, + "optional": false + }, + { + "name": "omittedMessages", + "type": 17, + "optional": false + }, + { + "name": "originalMessages", + "type": 17, + "optional": false + }, + { + "name": "retainedMessages", + "type": 17, + "optional": false + }, + { + "name": "sessionId", + "type": 4, + "optional": false + }, + { + "name": "truncated", + "type": 157, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 156 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 162 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 160, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 161, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 176, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 178, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 143, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#UserMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts:162" + ] + }, { "digest": "658d895d187b26d83f3b53109a3bf77bbfba9f6f9a6d4bc4ee4315b4eb36239e", "schema": { @@ -37068,6 +54008,97 @@ "packages/experimental/agent-team/src/types.ts:47" ] }, + { + "digest": "65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#SystemPromptMessageSource" + ], + "sources": [ + "packages/llm/llm/src/message.ts:35" + ] + }, + { + "digest": "66ba70f6f068da443f969a0b947a013c3addd776b9b60a0a393759c19825e9a2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "deferLoading", + "type": 1, + "optional": true + }, + { + "name": "description", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "parameters", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 2, + "value": 4 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ToolSchema" + ], + "sources": [ + "packages/llm/llm/src/types.ts:461" + ] + }, { "digest": "66ece68282d8c06330fb83329a24ae54c386d5ccfab296bbf18369da8beb7d14", "schema": { @@ -37277,85 +54308,7 @@ "sources": [] }, { - "digest": "693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 1, - "optional": false - }, - { - "name": "kind", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 2, - "optional": false - }, - { - "name": "message", - "type": 2, - "optional": false - }, - { - "name": "offloadImages", - "type": 3, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 3, - "optional": true - }, - { - "name": "requestId", - "type": 2, - "optional": true - }, - { - "name": "status", - "type": 3, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "error" - } - ] - }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6].reason[1]" - ], - "sources": [ - "packages/llm/llm/src/types.ts:148" - ] - }, - { - "digest": "69becfb6b2d3fd5da91518089454cae8ef33f1835637ec44dde35dd077fd4bae", + "digest": "69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1", "schema": { "root": 0, "nodes": [ @@ -37379,12 +54332,12 @@ }, { "name": "sourceEventSeqs", - "type": 47, + "type": 34, "optional": true }, { "name": "surfaceOp", - "type": 48, + "type": 35, "optional": false }, { @@ -37394,7 +54347,7 @@ }, { "name": "type", - "type": 52, + "type": 39, "optional": false } ], @@ -37436,12 +54389,12 @@ }, { "name": "role", - "type": 29, + "type": 31, "optional": false }, { "name": "source", - "type": 30, + "type": 32, "optional": false } ], @@ -37458,8 +54411,9 @@ 8, 19, 22, - 25, - 27 + 24, + 26, + 29 ] }, { @@ -37656,35 +54610,21 @@ "kind": "object", "properties": [ { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 23, - "optional": true - }, - { - "name": "toolCallId", + "name": "text", "type": 6, "optional": false }, { "name": "type", - "type": 24, + "type": 23, "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "boolean" - }, { "kind": "literal", - "value": "tool-result" + "value": "text" }, { "kind": "object", @@ -37696,7 +54636,7 @@ }, { "name": "type", - "type": 26, + "type": 25, "optional": false } ], @@ -37710,7 +54650,12 @@ "kind": "object", "properties": [ { - "name": "text", + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", "type": 6, "optional": false }, @@ -37722,225 +54667,52 @@ ], "indices": [] }, + { + "kind": "primitive", + "type": "never" + }, { "kind": "literal", - "value": "text" + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" }, { "kind": "literal", "value": "system" }, - { - "kind": "union", - "types": [ - 31, - 36, - 38, - 40, - 42, - 44, - 46 - ] - }, { "kind": "object", "properties": [ - { - "name": "form", - "type": 32, - "optional": false - }, { "name": "kind", "type": 33, "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - }, - { - "name": "sections", - "type": 34, - "optional": false } ], "indices": [] }, { "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 35 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 37, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - }, - { - "name": "summary", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 39, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 41, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 45, - "optional": false - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] + "value": "system-prompt" }, { "kind": "array", @@ -37949,8 +54721,8 @@ { "kind": "union", "types": [ - 49, - 51 + 36, + 38 ] }, { @@ -37963,7 +54735,7 @@ }, { "name": "op", - "type": 50, + "type": 37, "optional": false }, { @@ -37988,11 +54760,2921 @@ } ] }, - "names": [ - "event:system/message" - ], + "names": [], "sources": [] }, + { + "digest": "691c0f641cd3e8072fdacd6fa8c400253cf75a0ce9285d8ce89141bbb24f2fb6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 33, + 195, + 196, + 198 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "isError", + "type": 30, + "optional": true + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false + }, + { + "name": "toolCallId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 34, + "optional": false + }, + { + "name": "source", + "type": 35, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 32, + 36, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 54, + 56, + 58, + 60, + 62, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 115, + 117, + 120, + 121, + 122, + 123, + 124, + 126, + 127, + 128, + 129, + 131, + 132, + 133, + 134, + 135, + 137, + 139, + 140, + 142, + 143, + 151, + 152, + 154, + 156, + 160, + 162, + 169, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 187, + 189, + 190, + 191, + 192, + 193, + 194 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 114, + "optional": false + }, + { + "name": "revision", + "type": 18, + "optional": false + }, + { + "name": "round", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 116, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 118, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 119, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 125, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 63, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 130, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 136, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 138, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 141, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 25, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 144, + "optional": false + }, + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 145 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 146, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 147, + 148, + 149 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 138, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 155, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 157, + "optional": false + }, + { + "name": "form", + "type": 100, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "update", + "type": 25, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 158 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 52, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 72, + "optional": false + }, + { + "name": "kind", + "type": 163, + "optional": false + }, + { + "name": "references", + "type": 164, + "optional": false + }, + { + "name": "version", + "type": 168, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 165 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 18, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 166, + "optional": false + }, + { + "name": "compacted", + "type": 30, + "optional": false + }, + { + "name": "inputIndex", + "type": 18, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 18, + "optional": false + }, + { + "name": "omittedMessages", + "type": 18, + "optional": false + }, + { + "name": "originalMessages", + "type": 18, + "optional": false + }, + { + "name": "retainedMessages", + "type": 18, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 167 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 172 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 63, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 170, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 186, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 86, + "optional": false + }, + { + "name": "kind", + "type": 188, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 37, + "optional": false + }, + { + "name": "kind", + "type": 63, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 138, + "optional": false + }, + { + "name": "source", + "type": 35, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 197, + "optional": false + }, + { + "name": "source", + "type": 117, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 199, + "optional": false + }, + { + "name": "source", + "type": 129, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#Message" + ], + "sources": [ + "packages/llm/llm/src/message.ts:196" + ] + }, + { + "digest": "693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "failure", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 2, + "optional": false + }, + { + "name": "message", + "type": 2, + "optional": false + }, + { + "name": "offloadImages", + "type": 3, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 3, + "optional": true + }, + { + "name": "requestId", + "type": 2, + "optional": true + }, + { + "name": "status", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + } + ] + }, + "names": [], + "sources": [ + "packages/llm/llm/src/types.ts:162" + ] + }, { "digest": "69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199", "schema": { @@ -38043,11 +57725,9 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[11]" - ], + "names": [], "sources": [ - "packages/api/session-controller/src/types.ts:381" + "packages/api/session-controller/src/types.ts:385" ] }, { @@ -38064,6 +57744,20 @@ "names": [], "sources": [] }, + { + "digest": "6b23ed9ce1b397e602788dbe033693bf97642a69e23fcab1cc45bf6f13b6d619", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "compact-checkpoint" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "6bbe793f6a93dc8d50a4d4d3fbb6f8ed15650bcb7e151d28669628f7b7c3fc25", "schema": { @@ -38163,6 +57857,379 @@ "packages/goal/goal/src/types.ts:60" ] }, + { + "digest": "6bc8e51124d0874bc89e1d0ceff381a9c3cd0fc240667d69f841ce4f60f65fe5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 1, + "optional": false + }, + { + "name": "step", + "type": 18, + "optional": false + }, + { + "name": "turn", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:330" + ] + }, { "digest": "6c03546143cdf6ae88f1745ac98c5139efa1588d1415249bbc5f3104d32ab800", "schema": { @@ -38185,11 +58252,9 @@ } ] }, - "names": [ - "event:turn/end.data.reason[1].reason[1]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:190" + "packages/core/session/src/types.ts:191" ] }, { @@ -38237,13 +58302,54 @@ } ] }, - "names": [ - "event:turn/end.data.reason[1].reason[2]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:191" + "packages/core/session/src/types.ts:192" ] }, + { + "digest": "6ccb6bc423fb3952458abf9c1b1c3284208b7e660344b612cc55da773d61afe4", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "6cda0d6d3b4336d83998fe580628426df81c2afbab5d768b8813b56d569120e8", "schema": { @@ -38258,61 +58364,6 @@ "names": [], "sources": [] }, - { - "digest": "6d63f25a28b70801937a46b1058be5f52d4efbaf3516141470463ae469b59c23", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "array", - "element": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - }, - { - "name": "parameters", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "object", - "properties": [], - "indices": [ - { - "key": 2, - "value": 4 - } - ] - }, - { - "kind": "opaque", - "reason": "unknown" - } - ] - }, - "names": [ - "event:request/header.data.header.tools" - ], - "sources": [] - }, { "digest": "6e52dd55a1d48954ed5464ec46fe34d9eb65f709baabc9561e7a279910b0c406", "schema": { @@ -38335,13 +58386,45 @@ } ] }, - "names": [ - "event:agent-preset/selected.data" - ], + "names": [], "sources": [ "packages/preset/agent-presets/src/session.ts:28" ] }, + { + "digest": "6ea608bdc8a7a63d3d23b84c49721325094db88d136482e43a820945295eee3e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "6ebcc2dbec9f2dabca9f668ae6d39e877899b180740570f453409db339221df3", "schema": { @@ -38481,6 +58564,40 @@ "packages/context/agent-instructions/src/state.ts:37" ] }, + { + "digest": "6f44f32be9bcd9a8bf075c3b575b06c8ed63446386e5b0995c7b73762e68ddae", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "6f611bed14b2106542480c4a230b4a83baf76dc0d8ac0cd13319a7cb8dae7675", "schema": { @@ -38695,9 +58812,7 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][1]" - ], + "names": [], "sources": [ "packages/llm/llm/src/assistant-stream.ts:28" ] @@ -38750,10 +58865,7 @@ } ] }, - "names": [ - "event:tool/result.data.meta[5]", - "event:tool/result.data.meta[5][0][5]" - ], + "names": [], "sources": [] }, { @@ -38771,53 +58883,72 @@ "sources": [] }, { - "digest": "757013fff5879d73d5753d8d1120faab56110e88ac3932485ab7e034d9e9ce61", + "digest": "7554565be416b0342053ee6a46256c9dab07c487349b4a5f10bab1edc151c619", "schema": { "root": 0, "nodes": [ { - "kind": "union", - "types": [ - 1, - 2, - 3, - 4, - 5, - 6 - ] + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] }, { "kind": "literal", - "value": "file" + "value": "recall" }, { "kind": "literal", - "value": "image" - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "literal", - "value": "tool-result" + "value": "tool-goal" } ] }, - "names": [ - "packages/llm/llm/src/types.ts#ContentBlockType" - ], - "sources": [ - "packages/llm/llm/src/types.ts:135" - ] + "names": [], + "sources": [] + }, + { + "digest": "756b5e23a5cb2c7f486f366a828f7461c88902af21125bd6810881f4ccbff6cc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "time-context" + } + ] + }, + "names": [], + "sources": [] }, { "digest": "7624ca28c61ca0eaa4f015140f3cea6e0c16cce2f2960fab5f531203d253903e", @@ -39098,9 +59229,7 @@ } ] }, - "names": [ - "event:goal/change" - ], + "names": [], "sources": [] }, { @@ -39118,948 +59247,18 @@ "sources": [] }, { - "digest": "77b8491f946edfc8cc77ebae3ba49183759da31ba2dfa83d4c9e9e618c4b91d2", + "digest": "78a9be340090b735a39980e7222ce730c972fbcf1de7c9e0aef2125884b7caee", "schema": { "root": 0, "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "interrupted", - "type": 1, - "optional": true - }, - { - "name": "message", - "type": 2, - "optional": false - }, - { - "name": "step", - "type": 10, - "optional": false - }, - { - "name": "stream", - "type": 32, - "optional": false - }, - { - "name": "turn", - "type": 10, - "optional": false - }, - { - "name": "usage", - "type": 69, - "optional": true - } - ], - "indices": [] - }, { "kind": "literal", - "value": true - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "role", - "type": 28, - "optional": false - }, - { - "name": "source", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 5, - 8, - 18, - 21, - 24, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 9, - "optional": false - }, - { - "name": "offloaded", - "type": 1, - "optional": true - }, - { - "name": "type", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 10, - "optional": false - }, - { - "name": "height", - "type": 10, - "optional": false - }, - { - "name": "mediaType", - "type": 11, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "originalDimensions", - "type": 16, - "optional": true - }, - { - "name": "width", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 12, - 13, - 14, - 15 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 10, - "optional": false - }, - { - "name": "width", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 19, - "optional": false - }, - { - "name": "type", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 22, - "optional": true - }, - { - "name": "toolCallId", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 30, - "optional": false - }, - { - "name": "model", - "type": 6, - "optional": false - }, - { - "name": "provider", - "type": 6, - "optional": false - }, - { - "name": "replayState", - "type": 31, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "array", - "element": 33 - }, - { - "kind": "union", - "types": [ - 34, - 38, - 71, - 73 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "args", - "type": 35, - "optional": false - }, - { - "name": "dt", - "type": 36, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "time0", - "type": 10, - "optional": false - }, - { - "name": "type", - "type": 37, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "array", - "element": 10 - }, - { - "kind": "literal", - "value": "tool-call-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "chunk", - "type": 39, - "optional": false - }, - { - "name": "time", - "type": 10, - "optional": false - }, - { - "name": "type", - "type": 70, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 40, - 42, - 44, - 47, - 49, - 51, - 67 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "argumentsDelta", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "type", - "type": 41, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 4, - "optional": false - }, - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "type", - "type": 43, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "block-end" - }, - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 45, - "optional": false - }, - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "type", - "type": 46, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 7, - 17, - 20, - 23, - 25, - 27 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 48, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 50, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 52, - "optional": false - }, - { - "name": "replayState", - "type": 64, - "optional": true - }, - { - "name": "type", - "type": 66, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 53, - 56, - 58, - 60, - 62 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 54, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 6, - "optional": false - }, - { - "name": "message", - "type": 6, - "optional": false - }, - { - "name": "offloadImages", - "type": 10, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 10, - "optional": true - }, - { - "name": "requestId", - "type": 6, - "optional": true - }, - { - "name": "status", - "type": 10, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 54, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 59, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 61, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "stop" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 63, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-calls" - }, - { - "kind": "object", - "properties": [ - { - "name": "blocks", - "type": 65, - "optional": true - }, - { - "name": "response", - "type": 31, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 31 - }, - { - "kind": "literal", - "value": "finish" - }, - { - "kind": "object", - "properties": [ - { - "name": "type", - "type": 68, - "optional": false - }, - { - "name": "usage", - "type": 69, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "usage" - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 10, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 10, - "optional": true - }, - { - "name": "inputTokens", - "type": 10, - "optional": false - }, - { - "name": "outputTokens", - "type": 10, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 10, - "optional": true - }, - { - "name": "totalTokens", - "type": 10, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "chunk" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 36, - "optional": false - }, - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "texts", - "type": 35, - "optional": false - }, - { - "name": "time0", - "type": 10, - "optional": false - }, - { - "name": "type", - "type": 72, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 36, - "optional": false - }, - { - "name": "index", - "type": 10, - "optional": false - }, - { - "name": "texts", - "type": 35, - "optional": false - }, - { - "name": "time0", - "type": 10, - "optional": false - }, - { - "name": "type", - "type": 74, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-chunks" + "value": "tmux-context" } ] }, - "names": [ - "event:assistant/message.data" - ], - "sources": [ - "packages/core/session/src/types.ts:321" - ] + "names": [], + "sources": [] }, { "digest": "79650cfa10aa3c52440328d85e8a25f0ffadc8d7efd784e3c0819d8bb74a1985", @@ -40132,11 +59331,9 @@ } ] }, - "names": [ - "event:turn/end.data.reason[3]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:211" + "packages/core/session/src/types.ts:212" ] }, { @@ -40201,9 +59398,7 @@ } ] }, - "names": [ - "event:todo/write.data" - ], + "names": [], "sources": [ "packages/todo/tool-todo/src/types.ts:31" ] @@ -40308,9 +59503,7 @@ } ] }, - "names": [ - "SessionEventEnvelope[6]" - ], + "names": [], "sources": [] }, { @@ -40347,6 +59540,537 @@ "packages/feedback/message-feedback/src/types.ts:46" ] }, + { + "digest": "7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 27, + "optional": true + }, + { + "name": "seq", + "type": 20, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 39, + "optional": true + }, + { + "name": "surfaceOp", + "type": 40, + "optional": false + }, + { + "name": "time", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 4, + "optional": false + }, + { + "name": "meta", + "type": 35, + "optional": true + }, + { + "name": "step", + "type": 20, + "optional": false + }, + { + "name": "turn", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "reason", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "isError", + "type": 32, + "optional": true + }, + { + "name": "role", + "type": 33, + "optional": false + }, + { + "name": "source", + "type": 34, + "optional": false + }, + { + "name": "toolCallId", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "union", + "types": [ + 7, + 9, + 11, + 14, + 16, + 18, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 27, + "optional": true + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "mediaType", + "type": 21, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 26, + "optional": true + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 22, + 23, + 24, + 25 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 20, + "optional": false + }, + { + "name": "width", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 30, + "optional": false + }, + { + "name": "type", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 3, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 3, + 20, + 32, + 36, + 37, + 38 + ] + }, + { + "kind": "array", + "element": 35 + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 35 + } + ] + }, + { + "kind": "array", + "element": 20 + }, + { + "kind": "union", + "types": [ + 41, + 42 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 20, + "optional": false + }, + { + "name": "op", + "type": 43, + "optional": false + }, + { + "name": "startSeq", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "tool/result" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "7d226b9fd95b4ba213d4237c22e930a91c3c769c95ca7f92977b9d625ba13438", "schema": { @@ -40658,6 +60382,128 @@ "packages/feedback/command-feedback/src/types.ts:27" ] }, + { + "digest": "7d65acf0a3a43a8f445ce5d3320b42eca492739fc931b2a7516bfb8368dc2c68", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "literal", + "value": "tool-removal" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ContentBlockType" + ], + "sources": [ + "packages/llm/llm/src/types.ts:149" + ] + }, + { + "digest": "7df62978a2b7de8540e714152297743e0a622209a46a5ac9513fc0fad73ca23b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "tmux-context" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "7eaef7a763ba5b949b8464bc8add8980a3a5ab566014b69787aeba71e5dfe07b", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "7f13860ee89a2d35ce09f958e85a04566cd59cb1de1d73a9619a9b631961dc71", "schema": { @@ -40672,59 +60518,6 @@ "names": [], "sources": [] }, - { - "digest": "7f5f2a8618c2ece530a18b1358b890fb57fb8c35705e47b66bff2296f8c6e889", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": false - }, - { - "name": "parameters", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "object", - "properties": [], - "indices": [ - { - "key": 1, - "value": 3 - } - ] - }, - { - "kind": "opaque", - "reason": "unknown" - } - ] - }, - "names": [ - "packages/llm/llm/src/types.ts#ToolSchema" - ], - "sources": [ - "packages/llm/llm/src/types.ts:447" - ] - }, { "digest": "7f7fd5a6b0064f597534b29ff62ef26e786dffccf5e14f654a7d4fcea2c35f04", "schema": { @@ -40816,9 +60609,7 @@ } ] }, - "names": [ - "event:compaction/prune" - ], + "names": [], "sources": [] }, { @@ -40927,6 +60718,359 @@ "packages/goal/goal/src/domain.ts:47" ] }, + { + "digest": "8064c03c87c357fd1575cb9395ce86e6dcbe2d275bf7717864a02cddf01827d5", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 4, + 6, + 9, + 11, + 13, + 24 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 7, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 14, + "optional": false + }, + { + "name": "offloaded", + "type": 22, + "optional": true + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "mediaType", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 21, + "optional": true + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 17, + 18, + 19, + 20 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 15, + "optional": false + }, + { + "name": "width", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 25, + "optional": false + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 15, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + } + ] + }, + "names": [ + "packages/llm/llm/src/types.ts#ContentBlock" + ], + "sources": [ + "packages/llm/llm/src/types.ts:151" + ] + }, + { + "digest": "80677c8c8b804189a0fde8aa70dd4ad7af8bb12dfd03027e8e023c8592c838bc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "8067b0d232c350f189738e60ee3c9939d46ca3b32b45db5525237b077893f649", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "time-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "811229eedcec57979dbadca7dbea832a59f8580cff30cb217fca5e2da16314bd", "schema": { @@ -40976,7 +61120,7 @@ "packages/llm/llm/src/types.ts#ReasoningBlock" ], "sources": [ - "packages/llm/llm/src/types.ts:67" + "packages/llm/llm/src/types.ts:68" ] }, { @@ -40993,6 +61137,40 @@ "names": [], "sources": [] }, + { + "digest": "825ca23416b1ea9d81442afead5cf9229a6fa05842f042135cc3aa9710a6a2d8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "user-approval" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809", "schema": { @@ -41034,13 +61212,68 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[17].entries[0]" - ], + "names": [], "sources": [ "packages/skill/tool-skill/src/index.ts:40" ] }, + { + "digest": "8338ee303e2bd448e9e6144069942f63e3cfd5868962bddc9347d7009e8919d6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "83d6916021eede8f2d83a1872716caa1efdec39a3681890996c55147187fdd12", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-removal" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "83da72c6857601c75da11212ef847f57d457b9c99f0a82246dcdff3e26700239", "schema": { @@ -41174,63 +61407,21 @@ ] }, { - "digest": "85e1bd563d6c80c1f377f99f91103fec4e315148a7330f3b3dae7c2d04e33b01", + "digest": "84bbfdce7d2eab5b0c53e72ff7406db856c8bfd621b965b72fd86598ba493bf7", "schema": { "root": 0, "nodes": [ { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 1, - "optional": false - }, - { - "name": "kind", - "type": 2, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - } - ], - "indices": [] + "kind": "array", + "element": 1 }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" - } - ] - }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[7]", - "event:system/message.data.message.source[6]" - ], - "sources": [] - }, - { - "digest": "86cf1e44038cb8b11659863dd0efafe682e41b9c782265c1d50e0a687debfc60", - "schema": { - "root": 0, - "nodes": [ { "kind": "union", "types": [ - 1, - 7, - 65, - 67 + 2, + 8, + 67, + 69 ] }, { @@ -41238,37 +61429,37 @@ "properties": [ { "name": "args", - "type": 2, + "type": 3, "optional": false }, { "name": "dt", - "type": 4, + "type": 5, "optional": false }, { "name": "id", - "type": 3, + "type": 4, "optional": false }, { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": true }, { "name": "time0", - "type": 5, + "type": 6, "optional": false }, { "name": "type", - "type": 6, + "type": 7, "optional": false } ], @@ -41276,7 +61467,7 @@ }, { "kind": "array", - "element": 3 + "element": 4 }, { "kind": "primitive", @@ -41284,7 +61475,7 @@ }, { "kind": "array", - "element": 5 + "element": 6 }, { "kind": "primitive", @@ -41299,17 +61490,17 @@ "properties": [ { "name": "chunk", - "type": 8, + "type": 9, "optional": false }, { "name": "time", - "type": 5, + "type": 6, "optional": false }, { "name": "type", - "type": 64, + "type": 66, "optional": false } ], @@ -41318,13 +61509,13 @@ { "kind": "union", "types": [ - 9, - 11, - 37, - 40, + 10, + 12, + 39, 42, 44, - 61 + 46, + 63 ] }, { @@ -41332,27 +61523,27 @@ "properties": [ { "name": "argumentsDelta", - "type": 3, + "type": 4, "optional": false }, { "name": "id", - "type": 3, + "type": 4, "optional": false }, { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": true }, { "name": "type", - "type": 10, + "type": 11, "optional": false } ], @@ -41367,17 +61558,17 @@ "properties": [ { "name": "block", - "type": 12, + "type": 13, "optional": false }, { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "type", - "type": 36, + "type": 38, "optional": false } ], @@ -41386,12 +61577,13 @@ { "kind": "union", "types": [ - 13, - 15, - 25, - 28, - 32, - 34 + 14, + 16, + 26, + 29, + 31, + 33, + 36 ] }, { @@ -41399,22 +61591,22 @@ "properties": [ { "name": "arguments", - "type": 3, + "type": 4, "optional": false }, { "name": "id", - "type": 3, + "type": 4, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": false }, { "name": "type", - "type": 14, + "type": 15, "optional": false } ], @@ -41429,17 +61621,17 @@ "properties": [ { "name": "attachment", - "type": 16, + "type": 17, "optional": false }, { "name": "offloaded", - "type": 23, + "type": 24, "optional": true }, { "name": "type", - "type": 24, + "type": 25, "optional": false } ], @@ -41450,37 +61642,37 @@ "properties": [ { "name": "attachmentId", - "type": 3, + "type": 4, "optional": false }, { "name": "bytes", - "type": 5, + "type": 6, "optional": false }, { "name": "height", - "type": 5, + "type": 6, "optional": false }, { "name": "mediaType", - "type": 17, + "type": 18, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": true }, { "name": "originalDimensions", - "type": 22, + "type": 23, "optional": true }, { "name": "width", - "type": 5, + "type": 6, "optional": false } ], @@ -41489,10 +61681,10 @@ { "kind": "union", "types": [ - 18, 19, 20, - 21 + 21, + 22 ] }, { @@ -41505,23 +61697,23 @@ }, { "kind": "literal", - "value": "image/gif" + "value": "image/webp" }, { "kind": "literal", - "value": "image/webp" + "value": "image/gif" }, { "kind": "object", "properties": [ { "name": "height", - "type": 5, + "type": 6, "optional": false }, { "name": "width", - "type": 5, + "type": 6, "optional": false } ], @@ -41540,12 +61732,12 @@ "properties": [ { "name": "attachment", - "type": 26, + "type": 27, "optional": false }, { "name": "type", - "type": 27, + "type": 28, "optional": false } ], @@ -41556,17 +61748,17 @@ "properties": [ { "name": "attachmentId", - "type": 3, + "type": 4, "optional": false }, { "name": "bytes", - "type": 5, + "type": 6, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": false } ], @@ -41576,55 +61768,17 @@ "kind": "literal", "value": "file" }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 29, - "optional": false - }, - { - "name": "isError", - "type": 30, - "optional": true - }, - { - "name": "toolCallId", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 31, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 12 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, { "kind": "object", "properties": [ { "name": "text", - "type": 3, + "type": 4, "optional": false }, { "name": "type", - "type": 33, + "type": 30, "optional": false } ], @@ -41639,7 +61793,32 @@ "properties": [ { "name": "text", - "type": 3, + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 34, + "optional": true + }, + { + "name": "toolName", + "type": 4, "optional": false }, { @@ -41650,9 +61829,33 @@ ], "indices": [] }, + { + "kind": "primitive", + "type": "never" + }, { "kind": "literal", - "value": "text" + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" }, { "kind": "literal", @@ -41663,17 +61866,17 @@ "properties": [ { "name": "blockType", - "type": 38, + "type": 40, "optional": false }, { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "type", - "type": 39, + "type": 41, "optional": false } ], @@ -41682,12 +61885,13 @@ { "kind": "union", "types": [ - 14, - 24, - 27, - 31, - 33, - 35 + 15, + 25, + 28, + 30, + 32, + 35, + 37 ] }, { @@ -41699,17 +61903,17 @@ "properties": [ { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "text", - "type": 3, + "type": 4, "optional": false }, { "name": "type", - "type": 41, + "type": 43, "optional": false } ], @@ -41724,17 +61928,17 @@ "properties": [ { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "text", - "type": 3, + "type": 4, "optional": false }, { "name": "type", - "type": 43, + "type": 45, "optional": false } ], @@ -41749,17 +61953,17 @@ "properties": [ { "name": "reason", - "type": 45, + "type": 47, "optional": false }, { "name": "replayState", - "type": 57, + "type": 59, "optional": true }, { "name": "type", - "type": 60, + "type": 62, "optional": false } ], @@ -41768,11 +61972,11 @@ { "kind": "union", "types": [ - 46, - 49, + 48, 51, 53, - 55 + 55, + 57 ] }, { @@ -41780,12 +61984,12 @@ "properties": [ { "name": "failure", - "type": 47, + "type": 49, "optional": false }, { "name": "kind", - "type": 48, + "type": 50, "optional": false } ], @@ -41796,32 +62000,32 @@ "properties": [ { "name": "code", - "type": 3, + "type": 4, "optional": false }, { "name": "message", - "type": 3, + "type": 4, "optional": false }, { "name": "offloadImages", - "type": 5, + "type": 6, "optional": true }, { "name": "providerRetryAfterMs", - "type": 5, + "type": 6, "optional": true }, { "name": "requestId", - "type": 3, + "type": 4, "optional": true }, { "name": "status", - "type": 5, + "type": 6, "optional": true } ], @@ -41836,12 +62040,12 @@ "properties": [ { "name": "failure", - "type": 47, + "type": 49, "optional": false }, { "name": "kind", - "type": 50, + "type": 52, "optional": false } ], @@ -41856,7 +62060,7 @@ "properties": [ { "name": "kind", - "type": 52, + "type": 54, "optional": false } ], @@ -41871,7 +62075,7 @@ "properties": [ { "name": "kind", - "type": 54, + "type": 56, "optional": false } ], @@ -41886,7 +62090,7 @@ "properties": [ { "name": "kind", - "type": 56, + "type": 58, "optional": false } ], @@ -41901,12 +62105,12 @@ "properties": [ { "name": "blocks", - "type": 58, + "type": 60, "optional": true }, { "name": "response", - "type": 59, + "type": 61, "optional": false } ], @@ -41914,7 +62118,7 @@ }, { "kind": "array", - "element": 59 + "element": 61 }, { "kind": "opaque", @@ -41929,12 +62133,12 @@ "properties": [ { "name": "type", - "type": 62, + "type": 64, "optional": false }, { "name": "usage", - "type": 63, + "type": 65, "optional": false } ], @@ -41949,32 +62153,32 @@ "properties": [ { "name": "cacheReadTokens", - "type": 5, + "type": 6, "optional": true }, { "name": "cacheWriteTokens", - "type": 5, + "type": 6, "optional": true }, { "name": "inputTokens", - "type": 5, + "type": 6, "optional": false }, { "name": "outputTokens", - "type": 5, + "type": 6, "optional": false }, { "name": "reasoningTokens", - "type": 5, + "type": 6, "optional": true }, { "name": "totalTokens", - "type": 5, + "type": 6, "optional": true } ], @@ -41989,27 +62193,27 @@ "properties": [ { "name": "dt", - "type": 4, + "type": 5, "optional": false }, { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "texts", - "type": 2, + "type": 3, "optional": false }, { "name": "time0", - "type": 5, + "type": 6, "optional": false }, { "name": "type", - "type": 66, + "type": 68, "optional": false } ], @@ -42024,27 +62228,27 @@ "properties": [ { "name": "dt", - "type": 4, + "type": 5, "optional": false }, { "name": "index", - "type": 5, + "type": 6, "optional": false }, { "name": "texts", - "type": 2, + "type": 3, "optional": false }, { "name": "time0", - "type": 5, + "type": 6, "optional": false }, { "name": "type", - "type": 68, + "type": 70, "optional": false } ], @@ -42056,12 +62260,133 @@ } ] }, - "names": [ - "packages/llm/llm/src/assistant-stream.ts#AssistantStreamRecord" - ], - "sources": [ - "packages/llm/llm/src/assistant-stream.ts:20" - ] + "names": [], + "sources": [] + }, + { + "digest": "854db3efdfb0cd39d30953b28703e519c121f1115cebfffc40369fe86c406dd1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "85f9b505b7bdff1f61845c4cea8f36fd0fde1b62facbe87d8924d1d27e616f3a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-addition" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "85fe96bf15d5c7559eec3bae4d6cf1a76fda9f5be05a29c2830cff560cab0c0d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "time-context" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "8620189c8e33582708ece48fd2d20dc4d57912486a17bdbb9aea4c44f7018062", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + } + ] + }, + "names": [], + "sources": [] }, { "digest": "86d1d0e9cfebb240421187e3dc37fb71cc38a1501885cf32f8f9adef7b0a2bde", @@ -42228,7 +62553,7 @@ "packages/llm/llm/src/message.ts#ContextSnapshotSection" ], "sources": [ - "packages/llm/llm/src/message.ts:65" + "packages/llm/llm/src/message.ts:70" ] }, { @@ -42245,6 +62570,103 @@ "names": [], "sources": [] }, + { + "digest": "87b1a33564b9a4d63b00988a524c12259243953aebb9c9a05127d87b27464df9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "88841202942c7683b3b7e5ea6a796047ec326b6701ac23e58cc236d85613b9fa", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a", "schema": { @@ -42295,13 +62717,36 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[3]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:430" + "packages/llm/llm/src/types.ts:444" ] }, + { + "digest": "8a046b52331959aa3394680d6acbe09b8a5447c6b61375f263445bfcef19b7f1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0", "schema": { @@ -42402,9 +62847,7 @@ } ] }, - "names": [ - "event:hook/invoked" - ], + "names": [], "sources": [] }, { @@ -42429,9 +62872,7 @@ } ] }, - "names": [ - "event:permission/preset.data" - ], + "names": [], "sources": [ "packages/interaction/permission-presets/src/index.ts:57" ] @@ -42492,9 +62933,7 @@ } ] }, - "names": [ - "event:hook/result.data" - ], + "names": [], "sources": [ "packages/hooks/hook-protocol/src/types.ts:31" ] @@ -42549,13 +62988,117 @@ } ] }, - "names": [ - "event:session-log-deepseek/delivery-accepted.data" - ], + "names": [], "sources": [ "packages/session/session-log-deepseek/src/types.ts:81" ] }, + { + "digest": "8c1c4f72755a78ea163523a46565316e36e9b644382eb48e6635c71a6f412dd2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "8c627d7a45fa406cea879a3922105e27ed4c3c7966e264afaf11ea7a330f2dd1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "8cdd3fdd295cee53035de16a1b23411716f75e9f994fe9510cac5d7fef605c76", "schema": { @@ -42570,671 +63113,6 @@ "names": [], "sources": [] }, - { - "digest": "8d2e5a3c4230e6ea6c0b5151f02241d0db02cd2551f2df1b6b9700cddcc0dca3", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 1, - "optional": false - }, - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "error", - "type": 28, - "optional": true - }, - { - "name": "isError", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "parentCallId", - "type": 6, - "optional": false - }, - { - "name": "rootCallId", - "type": 6, - "optional": false - }, - { - "name": "subCallId", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 4, - 8, - 10, - 12, - 14, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 5, - "optional": true - }, - { - "name": "toolCallId", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 15, - "optional": false - }, - { - "name": "offloaded", - "type": 23, - "optional": true - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 16, - "optional": false - }, - { - "name": "height", - "type": 16, - "optional": false - }, - { - "name": "mediaType", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "originalDimensions", - "type": 22, - "optional": true - }, - { - "name": "width", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 18, - 19, - 20, - 21 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 16, - "optional": false - }, - { - "name": "width", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 26, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "reason", - "type": 6, - "optional": true - } - ], - "indices": [] - } - ] - }, - "names": [ - "packages/core/tools/src/types.ts#PtcDispatchEventData" - ], - "sources": [ - "packages/core/tools/src/types.ts:20" - ] - }, - { - "digest": "8d6a011f3ef7096a4a922ef420458419ff6b20e1eaeece5d331db7585d2f08d6", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "tuple", - "elements": [ - { - "type": 1, - "optional": false, - "rest": false - } - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 2, - "optional": false - }, - { - "name": "isError", - "type": 25, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "union", - "types": [ - 1, - 4, - 7, - 9, - 11, - 22 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 12, - "optional": false - }, - { - "name": "offloaded", - "type": 20, - "optional": true - }, - { - "name": "type", - "type": 21, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 13, - "optional": false - }, - { - "name": "height", - "type": 13, - "optional": false - }, - { - "name": "mediaType", - "type": 14, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 19, - "optional": true - }, - { - "name": "width", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 15, - 16, - 17, - 18 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 13, - "optional": false - }, - { - "name": "width", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 23, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 13, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - } - ] - }, - "names": [ - "event:tool/result.data.message.content" - ], - "sources": [] - }, { "digest": "8e31bb958e9b015e6f8407eaade32217068159e816f3cc99c3ad76eb889732e0", "schema": { @@ -43306,11 +63184,56 @@ } ] }, + "names": [], + "sources": [ + "packages/llm/llm/src/types.ts:161" + ] + }, + { + "digest": "8e611bf46821e5003a1605a73560a6f56388295149d449dfe2142d5ec335f29c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 1, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-addition" + } + ] + }, "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6].reason[0]" + "packages/llm/llm/src/types.ts#ToolAdditionBlock" ], "sources": [ - "packages/llm/llm/src/types.ts:147" + "packages/llm/llm/src/types.ts:115" ] }, { @@ -43375,7 +63298,7 @@ ] }, { - "digest": "8ea13bcd983eab596dbfd41c5c2b62a0b318b71cd2a987a6fd752c6ced7e4489", + "digest": "8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4", "schema": { "root": 0, "nodes": [ @@ -43383,216 +63306,29 @@ "kind": "object", "properties": [ { - "name": "data", + "name": "form", "type": 1, "optional": false }, { - "name": "ignorable", - "type": 4, - "optional": true - }, - { - "name": "seq", - "type": 6, - "optional": false - }, - { - "name": "time", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 18, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "header", + "name": "kind", "type": 2, "optional": false - }, - { - "name": "reason", - "type": 13, - "optional": false - }, - { - "name": "startsSeries", - "type": 4, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "adapterDefaults", - "type": 3, - "optional": true - }, - { - "name": "config", - "type": 5, - "optional": false - }, - { - "name": "tools", - "type": 9, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "maxTokens", - "type": 4, - "optional": true - }, - { - "name": "reasoningEffort", - "type": 4, - "optional": true } ], "indices": [] }, { "kind": "literal", - "value": true - }, - { - "kind": "object", - "properties": [ - { - "name": "maxTokens", - "type": 6, - "optional": true - }, - { - "name": "model", - "type": 7, - "optional": false - }, - { - "name": "provider", - "type": 7, - "optional": false - }, - { - "name": "reasoningEffort", - "type": 7, - "optional": true - }, - { - "name": "stop", - "type": 8, - "optional": true - }, - { - "name": "temperature", - "type": 6, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 7 - }, - { - "kind": "array", - "element": 10 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "parameters", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [], - "indices": [ - { - "key": 7, - "value": 12 - } - ] - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "union", - "types": [ - 14, - 15, - 16, - 17 - ] + "value": "relay" }, { "kind": "literal", - "value": "initial" - }, - { - "kind": "literal", - "value": "resume" - }, - { - "kind": "literal", - "value": "series" - }, - { - "kind": "literal", - "value": "change" - }, - { - "kind": "literal", - "value": "request/header" + "value": "tool-goal" } ] }, - "names": [ - "event:request/header" - ], + "names": [], "sources": [] }, { @@ -43636,11 +63372,36 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request.data.body.messages[0].content" - ], + "names": [], "sources": [] }, + { + "digest": "8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + } + ] + }, + "names": [], + "sources": [ + "packages/core/tools/src/index.ts:34" + ] + }, { "digest": "904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd", "schema": { @@ -43668,329 +63429,9 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[16].changes[0].action" - ], + "names": [], "sources": [] }, - { - "digest": "90c811b8c2668898515e69a24e82caffeb08517f9c7aa193867ff0380f3b535d", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 1, - "optional": false - }, - { - "name": "index", - "type": 15, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 2, - 7, - 9, - 11, - 13, - 24 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 4, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 1 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 14, - "optional": false - }, - { - "name": "offloaded", - "type": 22, - "optional": true - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 15, - "optional": false - }, - { - "name": "height", - "type": 15, - "optional": false - }, - { - "name": "mediaType", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 21, - "optional": true - }, - { - "name": "width", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 17, - 18, - 19, - 20 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 15, - "optional": false - }, - { - "name": "width", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 25, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 15, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "literal", - "value": "block-end" - } - ] - }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[4]" - ], - "sources": [ - "packages/llm/llm/src/types.ts:431" - ] - }, { "digest": "930a6567a10bb62ddd157bd8abdf4b182810c8c3b49d91309b3b009a5fed9731", "schema": { @@ -44131,9 +63572,7 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request.data.body" - ], + "names": [], "sources": [ "packages/web/web-search-deepseek/src/provider.ts:61" ] @@ -44220,16 +63659,7 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][0].texts", - "event:assistant/attempt.data.stream[0][1].texts", - "event:assistant/attempt.data.stream[0][2].args", - "event:request/header.data.header.config.stop", - "event:subagent/descriptor.data[1].toolFilter.allow", - "event:subagent/descriptor.data[1].toolFilter.deny", - "event:team/task.data.task.blockedBy", - "event:team/task.data.task.writeScopes" - ], + "names": [], "sources": [] }, { @@ -44284,9 +63714,7 @@ } ] }, - "names": [ - "event:approval/decided.data" - ], + "names": [], "sources": [ "packages/interaction/user-approval/src/types.ts:55" ] @@ -44359,11 +63787,9 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[1]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:428" + "packages/llm/llm/src/types.ts:442" ] }, { @@ -44380,6 +63806,40 @@ "names": [], "sources": [] }, + { + "digest": "96bfb916a727cd4445a594df264c523fc039749a31bfed924b8cc7bb308a5bb0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "runtime-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "96f4a9c81fc0f940ef71528a8cc66731ae4cf1f40d79680c5fe3c39f96d7723c", "schema": { @@ -44456,13 +63916,540 @@ } ] }, - "names": [ - "event:sandbox/mode.data" - ], + "names": [], "sources": [ "packages/sandbox/sandbox-policy/src/session-mode.ts:33" ] }, + { + "digest": "99135d8a3937977955eaac5f8f04f930dcd1562f8450a54a51cde9b921dd59a6", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "model-selection" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "9947aa5938fe19a895298da412917acbf9ffb5093a73ab8baa257e6ae9e63a07", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 33 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 3, + "optional": false + }, + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "rawOutput", + "type": 5, + "optional": false + }, + { + "name": "shadowedRange", + "type": 30, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 31, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 4, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "summary", + "type": 5, + "optional": false + }, + { + "name": "usage", + "type": 32, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "union", + "types": [ + 7, + 9, + 11, + 14, + 16, + 18, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 3, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 4, + "optional": false + }, + { + "name": "width", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 2, + "optional": false + }, + { + "name": "bytes", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 4, + "optional": false + }, + { + "name": "start", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 4, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 4, + "optional": true + }, + { + "name": "inputTokens", + "type": 4, + "optional": false + }, + { + "name": "outputTokens", + "type": 4, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 4, + "optional": true + }, + { + "name": "totalTokens", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 2, + "optional": false + }, + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "model", + "type": 2, + "optional": false + }, + { + "name": "provider", + "type": 2, + "optional": false + }, + { + "name": "rawOutput", + "type": 5, + "optional": true + }, + { + "name": "shadowedRange", + "type": 30, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 31, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 4, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 2, + "optional": true + }, + { + "name": "summary", + "type": 5, + "optional": false + }, + { + "name": "usage", + "type": 32, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "998f22585a5d73ec005365e203f07fc3b3a029e82323fdda3fd7f13b0a9639d0", "schema": { @@ -44558,11 +64545,55 @@ } ] }, - "names": [ - "SessionEventEnvelope[39]", - "SessionEventEnvelope[52]", - "SessionEventEnvelope[55]" - ], + "names": [], + "sources": [] + }, + { + "digest": "99e7e7d7fed55ae6a3a648b35192f16ab1248ddcb0179a0e275128ac1487d7c7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-jobs" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "99f0e98184709ad10f27bfdeaafb4457d9d2b413f402331764798cdb7d3cbe4d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "hooks-codex" + } + ] + }, + "names": [], "sources": [] }, { @@ -44626,9 +64657,7 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request.data.body.messages[0]" - ], + "names": [], "sources": [ "packages/web/web-search-deepseek/src/provider.ts:64" ] @@ -44686,6 +64715,176 @@ "packages/workflow/tool-workflow/src/types.ts:20" ] }, + { + "digest": "9a930283b91d493d6347146f2475bb107294b379415ca02162354f46a64164f7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 1, + "optional": true + }, + { + "name": "config", + "type": 3, + "optional": false + }, + { + "name": "system", + "type": 7, + "optional": true + }, + { + "name": "tools", + "type": 8, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 2, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 2, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 4, + "optional": true + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 5, + "optional": true + }, + { + "name": "stop", + "type": 6, + "optional": true + }, + { + "name": "temperature", + "type": 4, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "array", + "element": 9 + }, + { + "kind": "object", + "properties": [ + { + "name": "deferLoading", + "type": 2, + "optional": true + }, + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "parameters", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 5, + "value": 11 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#EpochHeader" + ], + "sources": [ + "packages/core/session/src/types.ts:240" + ] + }, + { + "digest": "9ac52f0f84fec2eb9f71c2937e497d759db5ca0da4836d93a679d113684141f2", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "model-selection" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "9acbe713f3f641921dd3333b240aa72e176d795327c24e8d9db9b68b16771b49", "schema": { @@ -44714,6 +64913,2902 @@ "names": [], "sources": [] }, + { + "digest": "9bc85364d1f37d9c837db6a3bdd3d1d007d923cdc7401a3322be9f12fdc225fd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 1, + "optional": false + }, + { + "name": "messageSeqs", + "type": 2, + "optional": false + }, + { + "name": "messages", + "type": 3, + "optional": false + }, + { + "name": "route", + "type": 203, + "optional": false + }, + { + "name": "system", + "type": 10, + "optional": false + }, + { + "name": "titleProvider", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 1 + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 36, + 198, + 199, + 201 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "isError", + "type": 33, + "optional": true + }, + { + "name": "role", + "type": 34, + "optional": false + }, + { + "name": "source", + "type": 35, + "optional": false + }, + { + "name": "toolCallId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 12, + 14, + 16, + 26, + 29, + 31 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 9, + "optional": true + }, + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 10, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 10, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 1, + "optional": false + }, + { + "name": "width", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 10, + "optional": false + }, + { + "name": "bytes", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 37, + "optional": false + }, + { + "name": "source", + "type": 38, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 35, + 39, + 42, + 45, + 47, + 49, + 51, + 59, + 61, + 63, + 65, + 67, + 72, + 74, + 76, + 84, + 88, + 89, + 90, + 91, + 92, + 93, + 95, + 96, + 98, + 100, + 102, + 104, + 106, + 107, + 109, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 169, + 171, + 174, + 175, + 176, + 177, + 178, + 180, + 181, + 182, + 183, + 184, + 186, + 187, + 188, + 189, + 190, + 192, + 193, + 194, + 195, + 197 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 24, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 10, + "optional": true + }, + { + "name": "changes", + "type": 52, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 53 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 54, + "optional": false + }, + { + "name": "digest", + "type": 10, + "optional": true + }, + { + "name": "path", + "type": 10, + "optional": false + }, + { + "name": "scope", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 55, + 56, + 57 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 10, + "optional": true + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "rpcId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 62, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 10, + "optional": false + }, + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 66, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + }, + { + "name": "ruleId", + "type": 10, + "optional": false + }, + { + "name": "source", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 68, + "optional": false + }, + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "update", + "type": 24, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 69 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 78, + "optional": false + }, + { + "name": "references", + "type": 79, + "optional": false + }, + { + "name": "version", + "type": 83, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 80 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 1, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 81, + "optional": false + }, + { + "name": "compacted", + "type": 33, + "optional": false + }, + { + "name": "inputIndex", + "type": 1, + "optional": false + }, + { + "name": "label", + "type": 10, + "optional": false + }, + { + "name": "omittedBytes", + "type": 1, + "optional": false + }, + { + "name": "omittedMessages", + "type": 1, + "optional": false + }, + { + "name": "originalMessages", + "type": 1, + "optional": false + }, + { + "name": "retainedMessages", + "type": 1, + "optional": false + }, + { + "name": "sessionId", + "type": 10, + "optional": false + }, + { + "name": "truncated", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 1, + 82 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 87 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 94, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 105, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 85, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 86, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 108, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 111, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 105, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 105, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 94, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 77, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 105, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 110, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 105, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 70, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 168, + "optional": false + }, + { + "name": "revision", + "type": 1, + "optional": false + }, + { + "name": "round", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 170, + "optional": false + }, + { + "name": "messageId", + "type": 10, + "optional": false + }, + { + "name": "senderId", + "type": 10, + "optional": false + }, + { + "name": "senderName", + "type": 10, + "optional": false + }, + { + "name": "teamId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 172, + "optional": false + }, + { + "name": "model", + "type": 10, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + }, + { + "name": "replayState", + "type": 173, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 179, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 64, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 73, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 185, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 103, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 191, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 40, + "optional": false + }, + { + "name": "kind", + "type": 105, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 105, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 196, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 60, + "optional": false + }, + { + "name": "source", + "type": 38, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 200, + "optional": false + }, + { + "name": "source", + "type": 171, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 202, + "optional": false + }, + { + "name": "source", + "type": 184, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 10, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [ + "packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData" + ], + "sources": [ + "packages/session/session-title-llm/src/index.ts:34" + ] + }, { "digest": "9d80129e13edfb6feb03ed327e6085c6ef60b97ad074244b2f5fd4667424a6a4", "schema": { @@ -44777,9 +67872,7 @@ } ] }, - "names": [ - "event:image/offload.data.targets" - ], + "names": [], "sources": [] }, { @@ -44809,11 +67902,7 @@ } ] }, - "names": [ - "event:compaction/prune.data.shadowedRange", - "event:compaction/summary.data[0].shadowedRange", - "event:compaction/summary.data[1].shadowedRange" - ], + "names": [], "sources": [ "packages/compaction/compaction/src/types.ts:38", "packages/compaction/compaction/src/types.ts:84" @@ -44879,1569 +67968,105 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[19]" - ], + "names": [], "sources": [ "packages/webhook/webhook/src/types.ts:74" ] }, { - "digest": "9fe0e77a7816b7fdb4b953ec0e2f0cd7bbd22c5de5c3567e612d1b20eb0992e6", + "digest": "9f65c43e340bba31cdc0fc37bd93ccb68d5e9b36f47a68c207e95a8e68620a5d", "schema": { "root": 0, "nodes": [ { "kind": "object", "properties": [ - { - "name": "maxTokens", - "type": 1, - "optional": false - }, - { - "name": "messageSeqs", - "type": 2, - "optional": false - }, - { - "name": "messages", - "type": 3, - "optional": false - }, - { - "name": "route", - "type": 89, - "optional": false - }, - { - "name": "system", - "type": 8, - "optional": false - }, - { - "name": "titleProvider", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 1 - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 8, - "optional": false - }, - { - "name": "role", - "type": 30, - "optional": false - }, - { - "name": "source", - "type": 34, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "union", - "types": [ - 7, - 10, - 20, - 23, - 26, - 28 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 8, - "optional": false - }, - { - "name": "id", - "type": 8, - "optional": false - }, - { - "name": "name", - "type": 8, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 11, - "optional": false - }, - { - "name": "offloaded", - "type": 18, - "optional": true - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 8, - "optional": false - }, - { - "name": "bytes", - "type": 1, - "optional": false - }, - { - "name": "height", - "type": 1, - "optional": false - }, - { - "name": "mediaType", - "type": 12, - "optional": false - }, - { - "name": "name", - "type": 8, - "optional": true - }, - { - "name": "originalDimensions", - "type": 17, - "optional": true - }, - { - "name": "width", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 13, - 14, - 15, - 16 - ] - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 1, - "optional": false - }, - { - "name": "width", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 21, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 8, - "optional": false - }, - { - "name": "bytes", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 5, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 8, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 8, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 8, - "optional": false - }, - { - "name": "type", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "union", - "types": [ - 31, - 32, - 33 - ] - }, - { - "kind": "literal", - "value": "system" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 35, - 44, - 46, - 47, - 50, - 55, - 57, - 62, - 63, - 64, - 66, - 68, - 69, - 76, - 78, - 80, - 82, - 84, - 87, - 88 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 18, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 8, - "optional": true - }, - { - "name": "changes", - "type": 36, - "optional": false - }, { "name": "form", - "type": 42, + "type": 1, "optional": false }, { "name": "kind", - "type": 43, + "type": 2, "optional": false } ], "indices": [] }, - { - "kind": "array", - "element": 37 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 38, - "optional": false - }, - { - "name": "digest", - "type": 8, - "optional": true - }, - { - "name": "path", - "type": 8, - "optional": false - }, - { - "name": "scope", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 39, - 40, - 41 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, { "kind": "literal", "value": "instructions" }, { "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 8, - "optional": false - }, - { - "name": "kind", - "type": 45, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 8, - "optional": true - }, - { - "name": "kind", - "type": 33, - "optional": false - }, - { - "name": "rpcId", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 8, - "optional": false - }, - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 49, - "optional": false - }, - { - "name": "provider", - "type": 8, - "optional": false - }, - { - "name": "ruleId", - "type": 8, - "optional": false - }, - { - "name": "source", - "type": 8, - "optional": false - }, - { - "name": "summary", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 51, - "optional": false - }, - { - "name": "form", - "type": 53, - "optional": false - }, - { - "name": "kind", - "type": 54, - "optional": false - }, - { - "name": "update", - "type": 18, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 52 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 8, - "optional": false - }, - { - "name": "name", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 56, - "optional": false - }, - { - "name": "name", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 58, - "optional": false - }, - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - }, - { - "name": "sections", - "type": 60, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 61 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 8, - "optional": false - }, - { - "name": "text", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - }, - { - "name": "summary", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 65, - "optional": false - }, - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 67, - "optional": false - }, - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 53, - "optional": false - }, - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 65, - "optional": false - }, - { - "name": "kind", - "type": 70, - "optional": false - }, - { - "name": "references", - "type": 71, - "optional": false - }, - { - "name": "version", - "type": 75, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 72 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 1, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 73, - "optional": false - }, - { - "name": "compacted", - "type": 24, - "optional": false - }, - { - "name": "inputIndex", - "type": 1, - "optional": false - }, - { - "name": "label", - "type": 8, - "optional": false - }, - { - "name": "omittedBytes", - "type": 1, - "optional": false - }, - { - "name": "omittedMessages", - "type": 1, - "optional": false - }, - { - "name": "originalMessages", - "type": 1, - "optional": false - }, - { - "name": "retainedMessages", - "type": 1, - "optional": false - }, - { - "name": "sessionId", - "type": 8, - "optional": false - }, - { - "name": "truncated", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 1, - 74 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 48, - "optional": false - }, - { - "name": "kind", - "type": 77, - "optional": false - }, - { - "name": "senderSessionId", - "type": 8, - "optional": false - }, - { - "name": "summary", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 67, - "optional": false - }, - { - "name": "kind", - "type": 79, - "optional": false - }, - { - "name": "senderSessionId", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 8, - "optional": false - }, - { - "name": "kind", - "type": 81, - "optional": false - }, - { - "name": "revision", - "type": 1, - "optional": false - }, - { - "name": "round", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 83, - "optional": false - }, - { - "name": "messageId", - "type": 8, - "optional": false - }, - { - "name": "senderId", - "type": 8, - "optional": false - }, - { - "name": "senderName", - "type": 8, - "optional": false - }, - { - "name": "teamId", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 85, - "optional": false - }, - { - "name": "model", - "type": 8, - "optional": false - }, - { - "name": "provider", - "type": 8, - "optional": false - }, - { - "name": "replayState", - "type": 86, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 59, - "optional": false - }, - { - "name": "plugin", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 33, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "model", - "type": 8, - "optional": false - }, - { - "name": "provider", - "type": 8, - "optional": false - } - ], - "indices": [] + "value": "tmux-context" } ] }, - "names": [ - "packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData" - ], - "sources": [ - "packages/session/session-title-llm/src/index.ts:27" - ] + "names": [], + "sources": [] }, { - "digest": "9ff2ad8dddb836f75e8f6197fff2371323dfc396c3c6fb667e6e0b42fda79a5c", + "digest": "a0baff42eb900561f91032b6950a3925cf19c5c8d9ba33948ac69e4ac7dee573", "schema": { "root": 0, "nodes": [ + { + "kind": "array", + "element": 1 + }, { "kind": "object", "properties": [ { - "name": "compactionId", - "type": 1, - "optional": false - }, - { - "name": "llmStreamCall", + "name": "deferLoading", "type": 2, - "optional": false - }, - { - "name": "maxTokens", - "type": 3, "optional": true }, { - "name": "model", - "type": 1, - "optional": false - }, - { - "name": "provider", - "type": 1, - "optional": false - }, - { - "name": "rawOutput", - "type": 4, - "optional": false - }, - { - "name": "shadowedRange", - "type": 27, - "optional": false - }, - { - "name": "shadowedSeqs", - "type": 28, - "optional": false - }, - { - "name": "shadowedTokenCount", + "name": "description", "type": 3, "optional": false }, { - "name": "sourceCommandId", - "type": 1, - "optional": true - }, - { - "name": "summary", - "type": 4, + "name": "name", + "type": 3, "optional": false }, { - "name": "usage", - "type": 29, - "optional": true + "name": "parameters", + "type": 4, + "optional": false } ], "indices": [] }, - { - "kind": "primitive", - "type": "string" - }, { "kind": "literal", "value": true }, { "kind": "primitive", - "type": "number" + "type": "string" }, { - "kind": "array", - "element": 5 - }, - { - "kind": "union", - "types": [ - 6, - 9, - 11, - 13, - 15, - 24 + "kind": "object", + "properties": [], + "indices": [ + { + "key": 3, + "value": 5 + } ] }, { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 4, - "optional": false - }, - { - "name": "isError", - "type": 7, - "optional": true - }, - { - "name": "toolCallId", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 1, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": false - }, - { - "name": "type", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 16, - "optional": false - }, - { - "name": "offloaded", - "type": 2, - "optional": true - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 1, - "optional": false - }, - { - "name": "bytes", - "type": 3, - "optional": false - }, - { - "name": "height", - "type": 3, - "optional": false - }, - { - "name": "mediaType", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": true - }, - { - "name": "originalDimensions", - "type": 22, - "optional": true - }, - { - "name": "width", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 18, - 19, - 20, - 21 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 3, - "optional": false - }, - { - "name": "width", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 25, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 1, - "optional": false - }, - { - "name": "bytes", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 1, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "end", - "type": 3, - "optional": false - }, - { - "name": "start", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 3 - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 3, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 3, - "optional": true - }, - { - "name": "inputTokens", - "type": 3, - "optional": false - }, - { - "name": "outputTokens", - "type": 3, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 3, - "optional": true - }, - { - "name": "totalTokens", - "type": 3, - "optional": true - } - ], - "indices": [] + "kind": "opaque", + "reason": "unknown" } ] }, - "names": [ - "event:compaction/summary.data[0]" - ], + "names": [], "sources": [] }, { @@ -46523,9 +68148,7 @@ } ] }, - "names": [ - "event:agent-preset/selected" - ], + "names": [], "sources": [] }, { @@ -46542,6 +68165,99 @@ "names": [], "sources": [] }, + { + "digest": "a15a19ef63cf5d1b711db1d249821dab0cedcd3a9ad09137b47352c93841fd20", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "model-selection" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a16e567c8cd2c55cf1e911aed3c200c4e1f6febb1459ff2a9e7adf159afb68cb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "schedule" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a2066bd52f61218ba15b758def2641cc6a8bd3d4a594a488ee4c65be356d7e39", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "a2b49331716ba0a7078b026d145306a70eae64b7313c3e6204bd931e75ec3bb1", "schema": { @@ -46737,11 +68453,9 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:433" + "packages/llm/llm/src/types.ts:447" ] }, { @@ -46772,6 +68486,49 @@ "names": [], "sources": [] }, + { + "digest": "a3c6f1ea38e9a61d7a9706057ba65aabe02dfe6d9dd90d4736aa62325d874531", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa", "schema": { @@ -46901,272 +68658,11 @@ } ] }, - "names": [ - "event:team/task.data" - ], + "names": [], "sources": [ "packages/experimental/agent-team/src/types.ts:223" ] }, - { - "digest": "a5a8c15f08af1b0f26f40906e0797b6b0920fd01069e660becce35ab7fc48d77", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "union", - "types": [ - 1, - 3, - 5, - 10, - 23, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "interrupted" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "error", - "type": 6, - "optional": false - }, - { - "name": "kind", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 7, - "optional": false - }, - { - "name": "message", - "type": 7, - "optional": false - }, - { - "name": "offloadImages", - "type": 8, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 8, - "optional": true - }, - { - "name": "requestId", - "type": 7, - "optional": true - }, - { - "name": "status", - "type": 8, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 11, - "optional": false - }, - { - "name": "reason", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "union", - "types": [ - 13, - 15, - 17, - 19, - 21 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "disposed" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 16, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "legacy" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 18, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "parent" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 20, - "optional": false - }, - { - "name": "reason", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "hook" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "blocked" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "completed" - } - ] - }, - "names": [ - "packages/core/session/src/types.ts#TurnEndReason" - ], - "sources": [ - "packages/core/session/src/types.ts:224" - ] - }, { "digest": "a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc", "schema": { @@ -47252,1134 +68748,9 @@ } ] }, - "names": [ - "event:subagent/model-selection-policy" - ], + "names": [], "sources": [] }, - { - "digest": "a6a195c1b4a906d953d24ab5864c9f1881d545460e080a51144adfc9cb058cfe", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "inserted", - "type": 1, - "optional": false - }, - { - "name": "outcome", - "type": 85, - "optional": true - }, - { - "name": "removedCount", - "type": 10, - "optional": true - }, - { - "name": "start", - "type": 10, - "optional": false - }, - { - "name": "target", - "type": 86, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "role", - "type": 29, - "optional": false - }, - { - "name": "source", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 5, - 8, - 19, - 22, - 25, - 27 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 9, - "optional": false - }, - { - "name": "offloaded", - "type": 17, - "optional": true - }, - { - "name": "type", - "type": 18, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 10, - "optional": false - }, - { - "name": "height", - "type": 10, - "optional": false - }, - { - "name": "mediaType", - "type": 11, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": true - }, - { - "name": "originalDimensions", - "type": 16, - "optional": true - }, - { - "name": "width", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 12, - 13, - 14, - 15 - ] - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 10, - "optional": false - }, - { - "name": "width", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 20, - "optional": false - }, - { - "name": "type", - "type": 21, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 6, - "optional": false - }, - { - "name": "bytes", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 23, - "optional": true - }, - { - "name": "toolCallId", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 6, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 31, - 40, - 42, - 43, - 46, - 51, - 53, - 58, - 59, - 60, - 62, - 64, - 65, - 72, - 74, - 76, - 78, - 80, - 83, - 84 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 17, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 6, - "optional": true - }, - { - "name": "changes", - "type": 32, - "optional": false - }, - { - "name": "form", - "type": 38, - "optional": false - }, - { - "name": "kind", - "type": 39, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 33 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 34, - "optional": false - }, - { - "name": "digest", - "type": 6, - "optional": true - }, - { - "name": "path", - "type": 6, - "optional": false - }, - { - "name": "scope", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 35, - 36, - 37 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 6, - "optional": false - }, - { - "name": "kind", - "type": 41, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 6, - "optional": true - }, - { - "name": "kind", - "type": 29, - "optional": false - }, - { - "name": "rpcId", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 6, - "optional": false - }, - { - "name": "form", - "type": 44, - "optional": false - }, - { - "name": "kind", - "type": 45, - "optional": false - }, - { - "name": "provider", - "type": 6, - "optional": false - }, - { - "name": "ruleId", - "type": 6, - "optional": false - }, - { - "name": "source", - "type": 6, - "optional": false - }, - { - "name": "summary", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 47, - "optional": false - }, - { - "name": "form", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 50, - "optional": false - }, - { - "name": "update", - "type": 17, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 48 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 38, - "optional": false - }, - { - "name": "kind", - "type": 52, - "optional": false - }, - { - "name": "name", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 54, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - }, - { - "name": "sections", - "type": 56, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 57 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 6, - "optional": false - }, - { - "name": "text", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 44, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - }, - { - "name": "summary", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 38, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 61, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 63, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 61, - "optional": false - }, - { - "name": "kind", - "type": 66, - "optional": false - }, - { - "name": "references", - "type": 67, - "optional": false - }, - { - "name": "version", - "type": 71, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 68 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 10, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 69, - "optional": false - }, - { - "name": "compacted", - "type": 23, - "optional": false - }, - { - "name": "inputIndex", - "type": 10, - "optional": false - }, - { - "name": "label", - "type": 6, - "optional": false - }, - { - "name": "omittedBytes", - "type": 10, - "optional": false - }, - { - "name": "omittedMessages", - "type": 10, - "optional": false - }, - { - "name": "originalMessages", - "type": 10, - "optional": false - }, - { - "name": "retainedMessages", - "type": 10, - "optional": false - }, - { - "name": "sessionId", - "type": 6, - "optional": false - }, - { - "name": "truncated", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 10, - 70 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 44, - "optional": false - }, - { - "name": "kind", - "type": 73, - "optional": false - }, - { - "name": "senderSessionId", - "type": 6, - "optional": false - }, - { - "name": "summary", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 63, - "optional": false - }, - { - "name": "kind", - "type": 75, - "optional": false - }, - { - "name": "senderSessionId", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 6, - "optional": false - }, - { - "name": "kind", - "type": 77, - "optional": false - }, - { - "name": "revision", - "type": 10, - "optional": false - }, - { - "name": "round", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 79, - "optional": false - }, - { - "name": "messageId", - "type": 6, - "optional": false - }, - { - "name": "senderId", - "type": 6, - "optional": false - }, - { - "name": "senderName", - "type": 6, - "optional": false - }, - { - "name": "teamId", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 81, - "optional": false - }, - { - "name": "model", - "type": 6, - "optional": false - }, - { - "name": "provider", - "type": 6, - "optional": false - }, - { - "name": "replayState", - "type": 82, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "plugin", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 29, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "canceled" - }, - { - "kind": "union", - "types": [ - 87, - 88 - ] - }, - { - "kind": "literal", - "value": "next-step" - }, - { - "kind": "literal", - "value": "next-turn" - } - ] - }, - "names": [ - "event:agent/inbox/spliced.data" - ], - "sources": [ - "packages/core/agent/src/types.ts:87" - ] - }, { "digest": "a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb", "schema": { @@ -48443,6 +68814,20 @@ "packages/workflow/tool-workflow/src/types.ts:14" ] }, + { + "digest": "a720757f704a2512e9d2f20da4a093e582472176236a75ab8b8eb7aaff17d85a", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "tool-registry" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f", "schema": { @@ -48508,9 +68893,7 @@ } ] }, - "names": [ - "event:plan/mode" - ], + "names": [], "sources": [] }, { @@ -48545,12 +68928,9 @@ } ] }, - "names": [ - "event:tool/ptc-dispatch.data.error", - "event:tool/result.data.error" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:363", + "packages/core/session/src/types.ts:383", "packages/core/tools/src/types.ts:24" ] }, @@ -48606,9 +68986,7 @@ } ] }, - "names": [ - "event:command/run.data" - ], + "names": [], "sources": [ "packages/interaction/commands/src/types.ts:105" ] @@ -48627,6 +69005,447 @@ "names": [], "sources": [] }, + { + "digest": "a9059a81430b320792bbb7c2ee1f8f6c77ff71e40ee44c18aec72e157c522694", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "hooks-claude-code" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "a99ec0993c62c058e50af9f68922202a3b54f5e259bc2abf1915a73381d2316d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 1, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 2, + "optional": false + }, + { + "name": "maxTokens", + "type": 3, + "optional": true + }, + { + "name": "model", + "type": 1, + "optional": false + }, + { + "name": "provider", + "type": 1, + "optional": false + }, + { + "name": "rawOutput", + "type": 4, + "optional": false + }, + { + "name": "shadowedRange", + "type": 29, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 30, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 3, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 1, + "optional": true + }, + { + "name": "summary", + "type": 4, + "optional": false + }, + { + "name": "usage", + "type": 31, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 8, + 10, + 13, + 15, + 17, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 1, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 2, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 3, + "optional": false + }, + { + "name": "width", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 1, + "optional": false + }, + { + "name": "bytes", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 3, + "optional": false + }, + { + "name": "start", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 3, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 3, + "optional": true + }, + { + "name": "inputTokens", + "type": 3, + "optional": false + }, + { + "name": "outputTokens", + "type": 3, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 3, + "optional": true + }, + { + "name": "totalTokens", + "type": 3, + "optional": true + } + ], + "indices": [] + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "a99f76fd149051c363f960bfeeb5b9509587ecaf7591a42797e4bfe810d8987a", "schema": { @@ -48742,9 +69561,41 @@ } ] }, - "names": [ - "event:turn/start" - ], + "names": [], + "sources": [] + }, + { + "digest": "aa2bf9e82b9fdeb94a42af20031fffa30e4e23f01f4ac39757427d4c64c407f0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "user-approval" + } + ] + }, + "names": [], "sources": [] }, { @@ -48909,6 +69760,40 @@ "names": [], "sources": [] }, + { + "digest": "aae343bc3d663c83f2e8b5e1c7eea5d509dc7a5361bc8bd8b5ac3bb8d3b1ed56", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "model-selection" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7", "schema": { @@ -48931,13 +69816,10 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6].reason[2]", - "event:turn/end.data.reason[4]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:213", - "packages/llm/llm/src/types.ts:146" + "packages/core/session/src/types.ts:214", + "packages/llm/llm/src/types.ts:160" ] }, { @@ -48971,42 +69853,208 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[17].entries" - ], + "names": [], "sources": [] }, { - "digest": "acd36e1717d2b4ef9e98a8e6fac17ca1203f3f448e5bca51677f129a8f4999e2", + "digest": "ad0c38a0adb82a94c925456df41586d9b5f9202fca18593eae2213d4445b4585", "schema": { "root": 0, "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "header", + "type": 1, + "optional": false + }, + { + "name": "reason", + "type": 13, + "optional": false + }, + { + "name": "startsSeries", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "adapterDefaults", + "type": 2, + "optional": true + }, + { + "name": "config", + "type": 4, + "optional": false + }, + { + "name": "system", + "type": 8, + "optional": true + }, + { + "name": "tools", + "type": 9, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 3, + "optional": true + }, + { + "name": "reasoningEffort", + "type": 3, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "reasoningEffort", + "type": 6, + "optional": true + }, + { + "name": "stop", + "type": 7, + "optional": true + }, + { + "name": "temperature", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "array", + "element": 6 + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "array", + "element": 10 + }, + { + "kind": "object", + "properties": [ + { + "name": "deferLoading", + "type": 3, + "optional": true + }, + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "parameters", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [], + "indices": [ + { + "key": 6, + "value": 12 + } + ] + }, + { + "kind": "opaque", + "reason": "unknown" + }, { "kind": "union", "types": [ - 1, - 2, - 3 + 14, + 15, + 16, + 17 ] }, { "kind": "literal", - "value": "assistant" + "value": "initial" }, { "kind": "literal", - "value": "system" + "value": "resume" }, { "kind": "literal", - "value": "user" + "value": "series" + }, + { + "kind": "literal", + "value": "change" } ] }, - "names": [ - "event:session/title-llm-request.data.messages[0].role" - ], - "sources": [] + "names": [], + "sources": [ + "packages/core/session/src/types.ts:390" + ] }, { "digest": "ad22a5ca5bbaab2e1440779cd3648e85ddfc6f73b5207394eda699555cf31430", @@ -49073,19 +70121,50 @@ ] }, "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[0]", - "event:session/title.data.source[2]", - "event:turn/end.data.reason[1].reason[0]", "packages/interaction/commands/src/types.ts#CommandSource" ], "sources": [ - "packages/core/session/src/types.ts:189", + "packages/core/session/src/types.ts:190", "packages/interaction/commands/src/types.ts:75", "packages/interaction/commands/src/types.ts:79", - "packages/llm/llm/src/message.ts:103", + "packages/llm/llm/src/message.ts:111", "packages/session/session-title/src/types.ts:35" ] }, + { + "digest": "ade057f4fdc387aec6426f48704a1f9359cfc6fee13f27735b07f9b215ec16ca", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "tool-jobs" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "ae1f7110feeec697b8cab42b68f7709aa7b3279764099dfb53c25890d2e5c871", "schema": { @@ -49221,9 +70300,7 @@ } ] }, - "names": [ - "event:subagent/catalog" - ], + "names": [], "sources": [] }, { @@ -49268,6 +70345,20 @@ "names": [], "sources": [] }, + { + "digest": "af6e173f7be819bcd0a5c8d77918649c10ce761d8a184ff472f2e01ce64eb2e0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": 4 + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "aff60ef947c18b012644852bdd0d5bfe72065e061dd563787c76c646b4a10f6b", "schema": { @@ -49373,9 +70464,32 @@ } ] }, - "names": [ - "event:compaction/end" - ], + "names": [], + "sources": [] + }, + { + "digest": "b062078e899958f99ae464514578b8c093924dfe34bd9a835932b420ff2150b1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + } + ] + }, + "names": [], "sources": [] }, { @@ -49531,7 +70645,7 @@ "packages/core/session/src/types.ts#RequestContext" ], "sources": [ - "packages/core/session/src/types.ts:242" + "packages/core/session/src/types.ts:254" ] }, { @@ -49549,9 +70663,7 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks" - ], + "names": [], "sources": [] }, { @@ -49666,9 +70778,7 @@ } ] }, - "names": [ - "event:team/member.data" - ], + "names": [], "sources": [ "packages/experimental/agent-team/src/types.ts:221" ] @@ -49772,9 +70882,55 @@ } ] }, - "names": [ - "event:image/offload" - ], + "names": [], + "sources": [] + }, + { + "digest": "b2245a906e13aa94f2d3cc6cf7b04cfa0267f7b7f4d468de1b00b1a314e54626", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "forked" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b2a5c8c008a31e3dc6c3013502f2356aca13894b31c8e70601fa92f2d40d1dba", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + } + ] + }, + "names": [], "sources": [] }, { @@ -49817,418 +70973,7 @@ ] }, { - "digest": "b33142af8176323ffbb20762541be81c1d51b60a60887803836e0b146e5bef0c", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "data", - "type": 1, - "optional": false - }, - { - "name": "ignorable", - "type": 24, - "optional": true - }, - { - "name": "seq", - "type": 17, - "optional": false - }, - { - "name": "time", - "type": 17, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 2, - "optional": false - }, - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "error", - "type": 29, - "optional": true - }, - { - "name": "isError", - "type": 6, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "parentCallId", - "type": 7, - "optional": false - }, - { - "name": "rootCallId", - "type": 7, - "optional": false - }, - { - "name": "subCallId", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 5, - 9, - 11, - 13, - 15, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 3, - "optional": false - }, - { - "name": "isError", - "type": 6, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 7, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 16, - "optional": false - }, - { - "name": "offloaded", - "type": 24, - "optional": true - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 17, - "optional": false - }, - { - "name": "height", - "type": 17, - "optional": false - }, - { - "name": "mediaType", - "type": 18, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": true - }, - { - "name": "originalDimensions", - "type": 23, - "optional": true - }, - { - "name": "width", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 19, - 20, - 21, - 22 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 17, - "optional": false - }, - { - "name": "width", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 27, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 17, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "reason", - "type": 7, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool/ptc-dispatch" - } - ] - }, - "names": [ - "event:tool/ptc-dispatch" - ], - "sources": [] - }, - { - "digest": "b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "literal", - "value": "disposed" - } - ] - }, - "names": [], - "sources": [] - }, - { - "digest": "b4d298d90c798fa4d1f5b030ce3ce8031c4c41beafdb05323bec8b2a06903b43", + "digest": "b3681c026a0b98e98b103f057dfd217fbe904129c090efd668253ec9aea7fece", "schema": { "root": 0, "nodes": [ @@ -50245,11 +70990,6 @@ "type": 2, "optional": false }, - { - "name": "plugin", - "type": 3, - "optional": false - }, { "name": "summary", "type": 3, @@ -50264,7 +71004,7 @@ }, { "kind": "literal", - "value": "plugin" + "value": "tmux-context" }, { "kind": "primitive", @@ -50272,10 +71012,46 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[5]", - "event:system/message.data.message.source[4]" - ], + "names": [], + "sources": [] + }, + { + "digest": "b38f206d59bad891fa58c89f97a0036987b3defe7685acbd318fa55eb85f9751", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "disposed" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b4ec0af39fd52ed971990e42f04e5be3204882e555c409eb330f8238eec21569", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + } + ] + }, + "names": [], "sources": [] }, { @@ -50444,9 +71220,312 @@ } ] }, - "names": [ - "event:feedback/message-put" - ], + "names": [], + "sources": [] + }, + { + "digest": "b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "union", + "types": [ + 2, + 5, + 7, + 10, + 12, + 14, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 8, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 15, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 18, + 19, + 20, + 21 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 26, + "optional": false + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + } + ] + }, + "names": [], "sources": [] }, { @@ -50559,9 +71638,7 @@ } ] }, - "names": [ - "event:feedback/record" - ], + "names": [], "sources": [] }, { @@ -50740,13 +71817,79 @@ } ] }, - "names": [ - "event:turn/end.data.reason[0]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:201" + "packages/core/session/src/types.ts:202" ] }, + { + "digest": "b6f94c17dd9bbd7cd57015198b7c7c88407f0e3b89faab176ca3c11c3d864d3e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-codex" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "b70f3e81fe11b7a5f2504fb47a4502fb8d9c8f0731fdfe8ddcaf9b41f5a6e196", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "b765ee31033cea463863faf3fc6a0a1b85c47c6a2f13fe1ce833abe56105114b", "schema": { @@ -50761,6 +71904,31 @@ "names": [], "sources": [] }, + { + "digest": "b79641a9d25e756636dc0c706fdf3c4583ccb7d4920e009e6e86c0759cf4de4c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "b79ada42962cad0190a9d465805260567621fa3a4abd757eb31e6016b52d5ab5", "schema": { @@ -50927,9 +72095,7 @@ } ] }, - "names": [ - "event:subagent/descriptor" - ], + "names": [], "sources": [] }, { @@ -50998,9 +72164,7 @@ } ] }, - "names": [ - "event:session/title.data.source[1]" - ], + "names": [], "sources": [ "packages/session/session-title/src/types.ts:30" ] @@ -51197,9 +72361,7 @@ } ] }, - "names": [ - "event:todo/write" - ], + "names": [], "sources": [] }, { @@ -51273,9 +72435,70 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request.data.body.messages" - ], + "names": [], + "sources": [] + }, + { + "digest": "ba4c40b4381e0dcdfab8fc9fc75b5c9b3e8f09ef56deeb1bec8e703b0ef8cd6d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], "sources": [] }, { @@ -51309,321 +72532,7 @@ } ] }, - "names": [ - "event:subagent/model-selection-policy.data.allowedModels" - ], - "sources": [] - }, - { - "digest": "bab768260853e13a7cf2e22e65af572a1e76a5b2c01f3cdc2ce09d39b87fb70b", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "data", - "type": 1, - "optional": false - }, - { - "name": "ignorable", - "type": 29, - "optional": true - }, - { - "name": "seq", - "type": 14, - "optional": false - }, - { - "name": "time", - "type": 14, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 2, - "optional": false - }, - { - "name": "turn", - "type": 14, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 3, - 5, - 7, - 9, - 11, - 16 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "blocked" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "completed" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "interrupted" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "error", - "type": 12, - "optional": false - }, - { - "name": "kind", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 13, - "optional": false - }, - { - "name": "message", - "type": 13, - "optional": false - }, - { - "name": "offloadImages", - "type": 14, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 14, - "optional": true - }, - { - "name": "requestId", - "type": 13, - "optional": true - }, - { - "name": "status", - "type": 14, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 17, - "optional": false - }, - { - "name": "reason", - "type": 18, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "union", - "types": [ - 19, - 21, - 23, - 25, - 27 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "disposed" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "legacy" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "parent" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 28, - "optional": false - }, - { - "name": "reason", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "hook" - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "turn/end" - } - ] - }, - "names": [ - "event:turn/end" - ], + "names": [], "sources": [] }, { @@ -51721,9 +72630,50 @@ } ] }, - "names": [ - "event:tool-workflow/agent-end" - ], + "names": [], + "sources": [] + }, + { + "digest": "baccc97ec34be6c4c78e95aa88c85c29820269479445e5b13f956cd64c5e286f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], "sources": [] }, { @@ -51821,310 +72771,21 @@ } ] }, - "names": [ - "event:approval/decided" - ], + "names": [], "sources": [] }, { - "digest": "bb72d86bc9ef0b3908bfa57ef98ccccae24d67d945c9f6869ca3cb8577889e75", + "digest": "bb94f3217aa56c8876bbff0b8460d6a73cbead545659abb29e76cd0cf2cb92d6", "schema": { "root": 0, "nodes": [ - { - "kind": "array", - "element": 1 - }, - { - "kind": "union", - "types": [ - 2, - 5, - 7, - 9, - 20, - 23 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, { "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 10, - "optional": false - }, - { - "name": "offloaded", - "type": 18, - "optional": true - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 3, - "optional": false - }, - { - "name": "bytes", - "type": 11, - "optional": false - }, - { - "name": "height", - "type": 11, - "optional": false - }, - { - "name": "mediaType", - "type": 12, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": true - }, - { - "name": "originalDimensions", - "type": 17, - "optional": true - }, - { - "name": "width", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 13, - 14, - 15, - 16 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 11, - "optional": false - }, - { - "name": "width", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 21, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 3, - "optional": false - }, - { - "name": "bytes", - "type": 11, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 0, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" + "value": "hooks-codex" } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].content", - "event:agent/inbox/spliced.data.inserted[0].content[0][5].content", - "event:assistant/message.data.message.content", - "event:compaction/summary.data[0].rawOutput", - "event:compaction/summary.data[0].summary", - "event:compaction/summary.data[1].rawOutput", - "event:compaction/summary.data[1].summary", - "event:session/title-llm-request.data.messages[0].content", - "event:system/message.data.message.content", - "event:team/message/queued.data.message.content", - "event:tool/ptc-dispatch.data.content" - ], + "names": [], "sources": [] }, { @@ -52138,14 +72799,7 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[8].replayState", - "event:assistant/attempt.data.stream[0][3].chunk[6].replayState.blocks[0]", - "event:assistant/attempt.data.stream[0][3].chunk[6].replayState.response", - "event:request/header.data.header.tools[0].parameters.[value]", - "event:tool/ptc-dispatch-start.data.arguments", - "event:tool/ptc-dispatch.data.arguments" - ], + "names": [], "sources": [] }, { @@ -52184,11 +72838,9 @@ } ] }, - "names": [ - "SessionEventEnvelope[6].surfaceOp[1]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:441" + "packages/core/session/src/types.ts:464" ] }, { @@ -52507,7 +73159,7 @@ "packages/llm/llm/src/types.ts#ToolCallBlock" ], "sources": [ - "packages/llm/llm/src/types.ts:104" + "packages/llm/llm/src/types.ts:105" ] }, { @@ -52580,9 +73232,7 @@ } ] }, - "names": [ - "event:tool-workflow/run-start" - ], + "names": [], "sources": [] }, { @@ -52648,7 +73298,7 @@ "sources": [] }, { - "digest": "c55a891c7aac496de6ee64c91c1fb65728c977314013033e42c863428aada854", + "digest": "c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49", "schema": { "root": 0, "nodes": [ @@ -52656,138 +73306,73 @@ "kind": "object", "properties": [ { - "name": "adapterDefaults", + "name": "form", "type": 1, - "optional": true - }, - { - "name": "config", - "type": 3, "optional": false }, { - "name": "tools", - "type": 7, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "maxTokens", + "name": "kind", "type": 2, - "optional": true + "optional": false }, { - "name": "reasoningEffort", - "type": 2, - "optional": true + "name": "sections", + "type": 3, + "optional": false } ], "indices": [] }, { "kind": "literal", - "value": true + "value": "snapshot" + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "array", + "element": 4 }, { "kind": "object", "properties": [ - { - "name": "maxTokens", - "type": 4, - "optional": true - }, - { - "name": "model", - "type": 5, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "reasoningEffort", - "type": 5, - "optional": true - }, - { - "name": "stop", - "type": 6, - "optional": true - }, - { - "name": "temperature", - "type": 4, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 5 - }, - { - "kind": "array", - "element": 8 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 5, - "optional": false - }, { "name": "name", "type": 5, "optional": false }, { - "name": "parameters", - "type": 9, + "name": "text", + "type": 5, "optional": false } ], "indices": [] }, { - "kind": "object", - "properties": [], - "indices": [ - { - "key": 5, - "value": 10 - } - ] - }, - { - "kind": "opaque", - "reason": "unknown" + "kind": "primitive", + "type": "string" } ] }, - "names": [ - "packages/core/session/src/types.ts#EpochHeader" - ], - "sources": [ - "packages/core/session/src/types.ts:232" - ] + "names": [], + "sources": [] + }, + { + "digest": "c5687b1313206a6ff334066047b6a0681611467dc4df8c5a8e71d0b6df39311f", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "cordis-host-runner" + } + ] + }, + "names": [], + "sources": [] }, { "digest": "c589e938cc0e4989df8b82abef6339de621f0dc4fe62c230d145b94996af7f92", @@ -52852,7 +73437,6 @@ ] }, "names": [ - "event:tool/result.data.meta", "packages/util/values/src/index.ts#JsonValue" ], "sources": [ @@ -52890,1204 +73474,7 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[4].sections" - ], - "sources": [] - }, - { - "digest": "c7b24be059d34d08929593049a1a81eaa3855166aacfe9d7603c0bc8bb728d56", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "union", - "types": [ - 1, - 4, - 6, - 8, - 19, - 22 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 9, - "optional": false - }, - { - "name": "offloaded", - "type": 17, - "optional": true - }, - { - "name": "type", - "type": 18, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 10, - "optional": false - }, - { - "name": "height", - "type": 10, - "optional": false - }, - { - "name": "mediaType", - "type": 11, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": true - }, - { - "name": "originalDimensions", - "type": 16, - "optional": true - }, - { - "name": "width", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 12, - 13, - 14, - 15 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 10, - "optional": false - }, - { - "name": "width", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 20, - "optional": false - }, - { - "name": "type", - "type": 21, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 10, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 23, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 0 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - } - ] - }, - "names": [ - "packages/llm/llm/src/types.ts#ContentBlock" - ], - "sources": [ - "packages/llm/llm/src/types.ts:137" - ] - }, - { - "digest": "c80c89da83c46db7a454f034c10f969e03cfb574859c7316e5bff683f5a14b0e", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "data", - "type": 1, - "optional": false - }, - { - "name": "ignorable", - "type": 26, - "optional": true - }, - { - "name": "seq", - "type": 2, - "optional": false - }, - { - "name": "time", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 72, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "step", - "type": 2, - "optional": false - }, - { - "name": "stream", - "type": 3, - "optional": false - }, - { - "name": "turn", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "union", - "types": [ - 5, - 10, - 68, - 70 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "args", - "type": 6, - "optional": false - }, - { - "name": "dt", - "type": 8, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": true - }, - { - "name": "time0", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 7 - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "literal", - "value": "tool-call-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "chunk", - "type": 11, - "optional": false - }, - { - "name": "time", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 67, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 12, - 14, - 40, - 43, - 45, - 47, - 64 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "argumentsDelta", - "type": 7, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": true - }, - { - "name": "type", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 15, - "optional": false - }, - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 39, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 16, - 18, - 28, - 31, - 35, - 37 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 7, - "optional": false - }, - { - "name": "id", - "type": 7, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 17, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 19, - "optional": false - }, - { - "name": "offloaded", - "type": 26, - "optional": true - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 2, - "optional": false - }, - { - "name": "height", - "type": 2, - "optional": false - }, - { - "name": "mediaType", - "type": 20, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": true - }, - { - "name": "originalDimensions", - "type": 25, - "optional": true - }, - { - "name": "width", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 21, - 22, - 23, - 24 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 2, - "optional": false - }, - { - "name": "width", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 29, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 7, - "optional": false - }, - { - "name": "bytes", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 32, - "optional": false - }, - { - "name": "isError", - "type": 33, - "optional": true - }, - { - "name": "toolCallId", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 34, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 15 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 36, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 38, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "block-end" - }, - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 41, - "optional": false - }, - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 42, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 17, - 27, - 30, - 34, - 36, - 38 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 44, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "text", - "type": 7, - "optional": false - }, - { - "name": "type", - "type": 46, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 48, - "optional": false - }, - { - "name": "replayState", - "type": 60, - "optional": true - }, - { - "name": "type", - "type": 63, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 49, - 52, - 54, - 56, - 58 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 51, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 7, - "optional": false - }, - { - "name": "message", - "type": 7, - "optional": false - }, - { - "name": "offloadImages", - "type": 2, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 2, - "optional": true - }, - { - "name": "requestId", - "type": 7, - "optional": true - }, - { - "name": "status", - "type": 2, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 50, - "optional": false - }, - { - "name": "kind", - "type": 53, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 57, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "stop" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 59, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-calls" - }, - { - "kind": "object", - "properties": [ - { - "name": "blocks", - "type": 61, - "optional": true - }, - { - "name": "response", - "type": 62, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 62 - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "literal", - "value": "finish" - }, - { - "kind": "object", - "properties": [ - { - "name": "type", - "type": 65, - "optional": false - }, - { - "name": "usage", - "type": 66, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "usage" - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 2, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 2, - "optional": true - }, - { - "name": "inputTokens", - "type": 2, - "optional": false - }, - { - "name": "outputTokens", - "type": 2, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 2, - "optional": true - }, - { - "name": "totalTokens", - "type": 2, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "chunk" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 8, - "optional": false - }, - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "texts", - "type": 6, - "optional": false - }, - { - "name": "time0", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 69, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-chunks" - }, - { - "kind": "object", - "properties": [ - { - "name": "dt", - "type": 8, - "optional": false - }, - { - "name": "index", - "type": 2, - "optional": false - }, - { - "name": "texts", - "type": 6, - "optional": false - }, - { - "name": "time0", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 71, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-chunks" - }, - { - "kind": "literal", - "value": "assistant/attempt" - } - ] - }, - "names": [ - "event:assistant/attempt" - ], + "names": [], "sources": [] }, { @@ -54104,718 +73491,6 @@ "names": [], "sources": [] }, - { - "digest": "c93b6f51b399607349b4bcc66b58e848a44250ffc1e2537207bd092dfff94192", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "chunk", - "type": 1, - "optional": false - }, - { - "name": "time", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 59, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 2, - 6, - 32, - 35, - 37, - 39, - 56 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "argumentsDelta", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 3, - "optional": false - }, - { - "name": "index", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": true - }, - { - "name": "type", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "literal", - "value": "tool-call-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "block", - "type": 7, - "optional": false - }, - { - "name": "index", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 31, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 8, - 10, - 20, - 23, - 27, - 29 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 3, - "optional": false - }, - { - "name": "id", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 11, - "optional": false - }, - { - "name": "offloaded", - "type": 18, - "optional": true - }, - { - "name": "type", - "type": 19, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 3, - "optional": false - }, - { - "name": "bytes", - "type": 4, - "optional": false - }, - { - "name": "height", - "type": 4, - "optional": false - }, - { - "name": "mediaType", - "type": 12, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": true - }, - { - "name": "originalDimensions", - "type": 17, - "optional": true - }, - { - "name": "width", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 13, - 14, - 15, - 16 - ] - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 4, - "optional": false - }, - { - "name": "width", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 21, - "optional": false - }, - { - "name": "type", - "type": 22, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 3, - "optional": false - }, - { - "name": "bytes", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 3, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 24, - "optional": false - }, - { - "name": "isError", - "type": 25, - "optional": true - }, - { - "name": "toolCallId", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 7 - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "literal", - "value": "block-end" - }, - { - "kind": "object", - "properties": [ - { - "name": "blockType", - "type": 33, - "optional": false - }, - { - "name": "index", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 34, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 9, - 19, - 22, - 26, - 28, - 30 - ] - }, - { - "kind": "literal", - "value": "block-start" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 4, - "optional": false - }, - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 36, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "index", - "type": 4, - "optional": false - }, - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 38, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text-delta" - }, - { - "kind": "object", - "properties": [ - { - "name": "reason", - "type": 40, - "optional": false - }, - { - "name": "replayState", - "type": 52, - "optional": true - }, - { - "name": "type", - "type": 55, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 41, - 44, - 46, - 48, - 50 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 43, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 3, - "optional": false - }, - { - "name": "message", - "type": 3, - "optional": false - }, - { - "name": "offloadImages", - "type": 4, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 4, - "optional": true - }, - { - "name": "requestId", - "type": 3, - "optional": true - }, - { - "name": "status", - "type": 4, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "aborted" - }, - { - "kind": "object", - "properties": [ - { - "name": "failure", - "type": 42, - "optional": false - }, - { - "name": "kind", - "type": 45, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "error" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 47, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 49, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "stop" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 51, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-calls" - }, - { - "kind": "object", - "properties": [ - { - "name": "blocks", - "type": 53, - "optional": true - }, - { - "name": "response", - "type": 54, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 54 - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "literal", - "value": "finish" - }, - { - "kind": "object", - "properties": [ - { - "name": "type", - "type": 57, - "optional": false - }, - { - "name": "usage", - "type": 58, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "usage" - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 4, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 4, - "optional": true - }, - { - "name": "inputTokens", - "type": 4, - "optional": false - }, - { - "name": "outputTokens", - "type": 4, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 4, - "optional": true - }, - { - "name": "totalTokens", - "type": 4, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "chunk" - } - ] - }, - "names": [ - "event:assistant/attempt.data.stream[0][3]" - ], - "sources": [ - "packages/llm/llm/src/assistant-stream.ts:44" - ] - }, { "digest": "c99e20441bf15341e9db54385e558e5c03d21dff2eb1ac08ccbf47c2d8747954", "schema": { @@ -54896,9 +73571,7 @@ } ] }, - "names": [ - "event:compaction/end.data" - ], + "names": [], "sources": [ "packages/compaction/compaction/src/types.ts:72" ] @@ -55062,6 +73735,40 @@ "packages/schedule/schedule/src/types.ts:72" ] }, + { + "digest": "cb1c8959e1726f82f9a3d2ef2bc90bf8c451a98fd56175e956022124c770c818", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "runtime-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "cbca49bde16b656d5b8fbe4a8a507769f7b594c6287782b809c03814941bc5e3", "schema": { @@ -55090,6 +73797,49 @@ "names": [], "sources": [] }, + { + "digest": "cda2345a9be9d139df49ccbd16dcba716f3440178bf20ff8b801fda1f5eb77dc", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670", "schema": { @@ -55215,9 +73965,7 @@ } ] }, - "names": [ - "event:llm/retry.data[0]" - ], + "names": [], "sources": [ "packages/llm/llm-retry/src/types.ts:17" ] @@ -55422,9 +74170,7 @@ } ] }, - "names": [ - "event:web/deepseek-search-llm-request" - ], + "names": [], "sources": [] }, { @@ -55522,6 +74268,2696 @@ "names": [], "sources": [] }, + { + "digest": "d1f27cf1650e5f59d5d6e95ce6dfd92b31757af076a8ab6418a70b6dbdd53621", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "role", + "type": 30, + "optional": false + }, + { + "name": "source", + "type": 31, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 32, + 35, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 61, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 105, + 107, + 110, + 111, + 112, + 113, + 115, + 116, + 117, + 118, + 120, + 121, + 122, + 123, + 124, + 126, + 127, + 128, + 130, + 131, + 132, + 140, + 142, + 143, + 145, + 147, + 151, + 153, + 161, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 179, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + }, + { + "name": "revision", + "type": 18, + "optional": false + }, + { + "name": "round", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 106, + "optional": false + }, + { + "name": "messageId", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 108, + "optional": false + }, + { + "name": "model", + "type": 5, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "replayState", + "type": 109, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 114, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 119, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 49, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 51, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 53, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 125, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 129, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 59, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 25, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 5, + "optional": true + }, + { + "name": "changes", + "type": 133, + "optional": false + }, + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 139, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 134 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 135, + "optional": false + }, + { + "name": "digest", + "type": 5, + "optional": true + }, + { + "name": "path", + "type": 5, + "optional": false + }, + { + "name": "scope", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 136, + 137, + 138 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 141, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 5, + "optional": true + }, + { + "name": "kind", + "type": 30, + "optional": false + }, + { + "name": "rpcId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 5, + "optional": false + }, + { + "name": "kind", + "type": 144, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 5, + "optional": false + }, + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + }, + { + "name": "provider", + "type": 5, + "optional": false + }, + { + "name": "ruleId", + "type": 5, + "optional": false + }, + { + "name": "source", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 148, + "optional": false + }, + { + "name": "form", + "type": 90, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "update", + "type": 25, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 149 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 36, + "optional": false + }, + { + "name": "kind", + "type": 152, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 62, + "optional": false + }, + { + "name": "kind", + "type": 154, + "optional": false + }, + { + "name": "references", + "type": 155, + "optional": false + }, + { + "name": "version", + "type": 160, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 18, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 157, + "optional": false + }, + { + "name": "compacted", + "type": 159, + "optional": false + }, + { + "name": "inputIndex", + "type": 18, + "optional": false + }, + { + "name": "label", + "type": 5, + "optional": false + }, + { + "name": "omittedBytes", + "type": 18, + "optional": false + }, + { + "name": "omittedMessages", + "type": 18, + "optional": false + }, + { + "name": "originalMessages", + "type": 18, + "optional": false + }, + { + "name": "retainedMessages", + "type": 18, + "optional": false + }, + { + "name": "sessionId", + "type": 5, + "optional": false + }, + { + "name": "truncated", + "type": 159, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 18, + 158 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 164 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 34, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 178, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 76, + "optional": false + }, + { + "name": "kind", + "type": 180, + "optional": false + }, + { + "name": "senderSessionId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 49, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 51, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 53, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 33, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "summary", + "type": 5, + "optional": false + } + ], + "indices": [] + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2", "schema": { @@ -55537,7 +76973,7 @@ "sources": [] }, { - "digest": "d3e447062a2847dad847dad5168a9508d92c484363dfc76fd82605aa7bd46285", + "digest": "d4b739491689cc6bb13d07ffac1a32239875abda364c0d5edd8f74faf5e9c00d", "schema": { "root": 0, "nodes": [ @@ -55545,13 +76981,18 @@ "kind": "object", "properties": [ { - "name": "reason", + "name": "block", "type": 1, "optional": false }, { - "name": "turn", - "type": 9, + "name": "index", + "type": 16, + "optional": false + }, + { + "name": "type", + "type": 28, "optional": false } ], @@ -55561,117 +77002,127 @@ "kind": "union", "types": [ 2, - 4, - 6, - 11, - 24, - 26 + 5, + 7, + 10, + 12, + 14, + 25 ] }, { "kind": "object", "properties": [ { - "name": "kind", + "name": "text", "type": 3, "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "interrupted" - }, - { - "kind": "object", - "properties": [ + }, { - "name": "kind", - "type": 5, + "name": "type", + "type": 4, "optional": false } ], "indices": [] }, - { - "kind": "literal", - "value": "max-tokens" - }, - { - "kind": "object", - "properties": [ - { - "name": "error", - "type": 7, - "optional": false - }, - { - "name": "kind", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "code", - "type": 8, - "optional": false - }, - { - "name": "message", - "type": 8, - "optional": false - }, - { - "name": "offloadImages", - "type": 9, - "optional": true - }, - { - "name": "providerRetryAfterMs", - "type": 9, - "optional": true - }, - { - "name": "requestId", - "type": 8, - "optional": true - }, - { - "name": "status", - "type": 9, - "optional": true - } - ], - "indices": [] - }, { "kind": "primitive", "type": "string" }, - { - "kind": "primitive", - "type": "number" - }, { "kind": "literal", - "value": "error" + "value": "reasoning" }, { "kind": "object", "properties": [ { - "name": "kind", - "type": 12, + "name": "text", + "type": 3, "optional": false }, { - "name": "reason", + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 8, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", "type": 13, "optional": false } @@ -55680,74 +77131,110 @@ }, { "kind": "literal", - "value": "aborted" + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 15, + "optional": false + }, + { + "name": "offloaded", + "type": 23, + "optional": true + }, + { + "name": "type", + "type": 24, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "height", + "type": 16, + "optional": false + }, + { + "name": "mediaType", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 22, + "optional": true + }, + { + "name": "width", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" }, { "kind": "union", "types": [ - 14, - 16, 18, + 19, 20, - 22 + 21 ] }, { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 15, - "optional": false - } - ], - "indices": [] + "kind": "literal", + "value": "image/gif" }, { "kind": "literal", - "value": "disposed" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 17, - "optional": false - } - ], - "indices": [] + "value": "image/jpeg" }, { "kind": "literal", - "value": "legacy" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 19, - "optional": false - } - ], - "indices": [] + "value": "image/png" }, { "kind": "literal", - "value": "parent" + "value": "image/webp" }, { "kind": "object", "properties": [ { - "name": "kind", - "type": 21, + "name": "height", + "type": 16, "optional": false }, { - "name": "reason", - "type": 8, + "name": "width", + "type": 16, "optional": false } ], @@ -55755,60 +77242,62 @@ }, { "kind": "literal", - "value": "hook" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 23, - "optional": false - } - ], - "indices": [] + "value": true }, { "kind": "literal", - "value": "user" + "value": "image" }, { "kind": "object", "properties": [ { - "name": "kind", - "type": 25, + "name": "attachment", + "type": 26, "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "blocked" - }, - { - "kind": "object", - "properties": [ + }, { - "name": "kind", + "name": "type", "type": 27, "optional": false } ], "indices": [] }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 16, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, { "kind": "literal", - "value": "completed" + "value": "file" + }, + { + "kind": "literal", + "value": "block-end" } ] }, - "names": [ - "event:turn/end.data" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:285" + "packages/llm/llm/src/types.ts:445" ] }, { @@ -55979,304 +77468,9 @@ } ] }, - "names": [ - "event:team/task" - ], + "names": [], "sources": [] }, - { - "digest": "d61574d68558c5a184429e70b04da393dd5460bf5cc3ddef814546e659bd5127", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "isError", - "type": 24, - "optional": true - }, - { - "name": "toolCallId", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "union", - "types": [ - 0, - 3, - 6, - 8, - 10, - 21 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 7, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 4, - "optional": false - }, - { - "name": "id", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 11, - "optional": false - }, - { - "name": "offloaded", - "type": 19, - "optional": true - }, - { - "name": "type", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 12, - "optional": false - }, - { - "name": "height", - "type": 12, - "optional": false - }, - { - "name": "mediaType", - "type": 13, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": true - }, - { - "name": "originalDimensions", - "type": 18, - "optional": true - }, - { - "name": "width", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 14, - 15, - 16, - 17 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 12, - "optional": false - }, - { - "name": "width", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 22, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 4, - "optional": false - }, - { - "name": "bytes", - "type": 12, - "optional": false - }, - { - "name": "name", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - } - ] - }, - "names": [ - "packages/llm/llm/src/types.ts#ToolResultBlock" - ], - "sources": [ - "packages/llm/llm/src/types.ts:114" - ] - }, { "digest": "d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9", "schema": { @@ -56352,9 +77546,7 @@ } ] }, - "names": [ - "event:session-log-deepseek/delivery-accepted" - ], + "names": [], "sources": [] }, { @@ -56371,6 +77563,40 @@ "names": [], "sources": [] }, + { + "digest": "d85590a5675c6e2fd8164e5792a6cceac714605b8ac228adae5ee668facb1490", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "d8f868c6b3e7189de6c1ffe2ea04794ea2aa31315b6347d12536e46020afac87", "schema": { @@ -56553,6 +77779,20 @@ "packages/llm/llm/src/message.ts:29" ] }, + { + "digest": "d9edf1862e4471d6ad8a106a3f4160e0643874368707d50ecd8e27e5ee7a2567", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "schedule" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "dacf3d5f3e4ff619c1320e64a48dec5e7ecd7870bece65fbd449a0e63adfa521", "schema": { @@ -56567,6 +77807,69 @@ "names": [], "sources": [] }, + { + "digest": "db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0", "schema": { @@ -56667,11 +77970,36 @@ } ] }, - "names": [ - "event:compaction/start" - ], + "names": [], "sources": [] }, + { + "digest": "dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + } + ] + }, + "names": [], + "sources": [ + "packages/core/tools/src/ptc.ts:14" + ] + }, { "digest": "dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc", "schema": { @@ -56686,6 +78014,2748 @@ "names": [], "sources": [] }, + { + "digest": "dc4bd7ac827f4b1f9236f9a157a4b4cc171a0588064a611e43edd95f62c68130", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "inserted", + "type": 1, + "optional": false + }, + { + "name": "outcome", + "type": 194, + "optional": true + }, + { + "name": "removedCount", + "type": 19, + "optional": true + }, + { + "name": "start", + "type": 19, + "optional": false + }, + { + "name": "target", + "type": 195, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 10, + 13, + 15, + 17, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 11, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 18, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 19, + "optional": false + }, + { + "name": "width", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "union", + "types": [ + 33, + 36, + 38, + 40, + 42, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 62, + 63, + 64, + 65, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 109, + 111, + 114, + 115, + 116, + 117, + 118, + 120, + 121, + 122, + 123, + 125, + 126, + 127, + 128, + 129, + 131, + 132, + 133, + 135, + 136, + 144, + 146, + 147, + 149, + 151, + 155, + 157, + 165, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 183, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 108, + "optional": false + }, + { + "name": "revision", + "type": 19, + "optional": false + }, + { + "name": "round", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 110, + "optional": false + }, + { + "name": "messageId", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 112, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "replayState", + "type": 113, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 119, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 124, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 130, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 26, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 6, + "optional": true + }, + { + "name": "changes", + "type": 137, + "optional": false + }, + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 143, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 138 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 139, + "optional": false + }, + { + "name": "digest", + "type": 6, + "optional": true + }, + { + "name": "path", + "type": 6, + "optional": false + }, + { + "name": "scope", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 140, + 141, + 142 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 145, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 6, + "optional": true + }, + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "rpcId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 6, + "optional": false + }, + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "ruleId", + "type": 6, + "optional": false + }, + { + "name": "source", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 152, + "optional": false + }, + { + "name": "form", + "type": 94, + "optional": false + }, + { + "name": "kind", + "type": 154, + "optional": false + }, + { + "name": "update", + "type": 26, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 153 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 43, + "optional": false + }, + { + "name": "kind", + "type": 156, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 66, + "optional": false + }, + { + "name": "kind", + "type": 158, + "optional": false + }, + { + "name": "references", + "type": 159, + "optional": false + }, + { + "name": "version", + "type": 164, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 160 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 19, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 161, + "optional": false + }, + { + "name": "compacted", + "type": 163, + "optional": false + }, + { + "name": "inputIndex", + "type": 19, + "optional": false + }, + { + "name": "label", + "type": 6, + "optional": false + }, + { + "name": "omittedBytes", + "type": 19, + "optional": false + }, + { + "name": "omittedMessages", + "type": 19, + "optional": false + }, + { + "name": "originalMessages", + "type": 19, + "optional": false + }, + { + "name": "retainedMessages", + "type": 19, + "optional": false + }, + { + "name": "sessionId", + "type": 6, + "optional": false + }, + { + "name": "truncated", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 19, + 162 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 168 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 166, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 182, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 80, + "optional": false + }, + { + "name": "kind", + "type": 184, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "canceled" + }, + { + "kind": "union", + "types": [ + 196, + 197 + ] + }, + { + "kind": "literal", + "value": "next-step" + }, + { + "kind": "literal", + "value": "next-turn" + } + ] + }, + "names": [], + "sources": [ + "packages/core/agent/src/types.ts:87" + ] + }, { "digest": "dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d", "schema": { @@ -56701,7 +80771,7 @@ "sources": [] }, { - "digest": "dda6e111a8ccfc12f6e742e977a1a4e3549e8c03732a5ff6c8d7c3d4bcb7a412", + "digest": "dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5", "schema": { "root": 0, "nodes": [ @@ -56717,10 +80787,39 @@ "name": "kind", "type": 2, "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "tool-jobs" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "dd6cc2bb2a8f28248347021ad93565360b196a042360b4cd16b569d3a2a91f2d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false }, { - "name": "plugin", - "type": 3, + "name": "kind", + "type": 2, "optional": false } ], @@ -56728,22 +80827,15 @@ }, { "kind": "literal", - "value": "instructions" + "value": "recall" }, { "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" + "value": "tool-jobs" } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[2]", - "event:system/message.data.message.source[1]" - ], + "names": [], "sources": [] }, { @@ -56774,6 +80866,40 @@ "names": [], "sources": [] }, + { + "digest": "deaae5cd30987d4f49398e8f9d994c125907e7f928300745fb1dbf15f145d0e7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "plan-mode" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "df5d9709b7db2a72510dc52052a23f0c38f39730af1504bab8bccabc14fae528", "schema": { @@ -56883,9 +81009,7 @@ } ] }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[15].references" - ], + "names": [], "sources": [] }, { @@ -56988,1187 +81112,7 @@ } ] }, - "names": [ - "event:step/end" - ], - "sources": [] - }, - { - "digest": "e0b5bf44c27bbfc6ab144239e3e4169c4d21146645e0e3121bbb359c3bc8591d", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "data", - "type": 1, - "optional": false - }, - { - "name": "ignorable", - "type": 19, - "optional": true - }, - { - "name": "seq", - "type": 2, - "optional": false - }, - { - "name": "time", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 91, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "maxTokens", - "type": 2, - "optional": false - }, - { - "name": "messageSeqs", - "type": 3, - "optional": false - }, - { - "name": "messages", - "type": 4, - "optional": false - }, - { - "name": "route", - "type": 90, - "optional": false - }, - { - "name": "system", - "type": 9, - "optional": false - }, - { - "name": "titleProvider", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "array", - "element": 5 - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 6, - "optional": false - }, - { - "name": "id", - "type": 9, - "optional": false - }, - { - "name": "role", - "type": 31, - "optional": false - }, - { - "name": "source", - "type": 35, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 7 - }, - { - "kind": "union", - "types": [ - 8, - 11, - 21, - 24, - 27, - 29 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 9, - "optional": false - }, - { - "name": "id", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 9, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 12, - "optional": false - }, - { - "name": "offloaded", - "type": 19, - "optional": true - }, - { - "name": "type", - "type": 20, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 9, - "optional": false - }, - { - "name": "bytes", - "type": 2, - "optional": false - }, - { - "name": "height", - "type": 2, - "optional": false - }, - { - "name": "mediaType", - "type": 13, - "optional": false - }, - { - "name": "name", - "type": 9, - "optional": true - }, - { - "name": "originalDimensions", - "type": 18, - "optional": true - }, - { - "name": "width", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 14, - 15, - 16, - 17 - ] - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 2, - "optional": false - }, - { - "name": "width", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 22, - "optional": false - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 9, - "optional": false - }, - { - "name": "bytes", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 6, - "optional": false - }, - { - "name": "isError", - "type": 25, - "optional": true - }, - { - "name": "toolCallId", - "type": 9, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 9, - "optional": false - }, - { - "name": "type", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 9, - "optional": false - }, - { - "name": "type", - "type": 30, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "union", - "types": [ - 32, - 33, - 34 - ] - }, - { - "kind": "literal", - "value": "system" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "literal", - "value": "user" - }, - { - "kind": "union", - "types": [ - 36, - 45, - 47, - 48, - 51, - 56, - 58, - 63, - 64, - 65, - 67, - 69, - 70, - 77, - 79, - 81, - 83, - 85, - 88, - 89 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "baseline", - "type": 19, - "optional": true - }, - { - "name": "baselineIdentity", - "type": 9, - "optional": true - }, - { - "name": "changes", - "type": 37, - "optional": false - }, - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 44, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 38 - }, - { - "kind": "object", - "properties": [ - { - "name": "action", - "type": 39, - "optional": false - }, - { - "name": "digest", - "type": 9, - "optional": true - }, - { - "name": "path", - "type": 9, - "optional": false - }, - { - "name": "scope", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 40, - 41, - 42 - ] - }, - { - "kind": "literal", - "value": "remove" - }, - { - "kind": "literal", - "value": "replace" - }, - { - "kind": "literal", - "value": "set" - }, - { - "kind": "literal", - "value": "instructions" - }, - { - "kind": "literal", - "value": "agent-instructions" - }, - { - "kind": "object", - "properties": [ - { - "name": "callId", - "type": 9, - "optional": false - }, - { - "name": "kind", - "type": 46, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool" - }, - { - "kind": "object", - "properties": [ - { - "name": "clientTimeZone", - "type": 9, - "optional": true - }, - { - "name": "kind", - "type": 34, - "optional": false - }, - { - "name": "rpcId", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "deliveryId", - "type": 9, - "optional": false - }, - { - "name": "form", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 50, - "optional": false - }, - { - "name": "provider", - "type": 9, - "optional": false - }, - { - "name": "ruleId", - "type": 9, - "optional": false - }, - { - "name": "source", - "type": 9, - "optional": false - }, - { - "name": "summary", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "notice" - }, - { - "kind": "literal", - "value": "webhook" - }, - { - "kind": "object", - "properties": [ - { - "name": "entries", - "type": 52, - "optional": false - }, - { - "name": "form", - "type": 54, - "optional": false - }, - { - "name": "kind", - "type": 55, - "optional": false - }, - { - "name": "update", - "type": 19, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 53 - }, - { - "kind": "object", - "properties": [ - { - "name": "description", - "type": 9, - "optional": false - }, - { - "name": "name", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "catalog" - }, - { - "kind": "literal", - "value": "skill-catalog" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 57, - "optional": false - }, - { - "name": "name", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "skill-invocation" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 59, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - }, - { - "name": "sections", - "type": 61, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "array", - "element": 62 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 9, - "optional": false - }, - { - "name": "text", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - }, - { - "name": "summary", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 43, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 66, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "recall" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 68, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "relay" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 54, - "optional": false - }, - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 66, - "optional": false - }, - { - "name": "kind", - "type": 71, - "optional": false - }, - { - "name": "references", - "type": 72, - "optional": false - }, - { - "name": "version", - "type": 76, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session-reference" - }, - { - "kind": "array", - "element": 73 - }, - { - "kind": "object", - "properties": [ - { - "name": "capturedFormatVersion", - "type": 2, - "optional": true - }, - { - "name": "capturedThroughSeq", - "type": 74, - "optional": false - }, - { - "name": "compacted", - "type": 25, - "optional": false - }, - { - "name": "inputIndex", - "type": 2, - "optional": false - }, - { - "name": "label", - "type": 9, - "optional": false - }, - { - "name": "omittedBytes", - "type": 2, - "optional": false - }, - { - "name": "omittedMessages", - "type": 2, - "optional": false - }, - { - "name": "originalMessages", - "type": 2, - "optional": false - }, - { - "name": "retainedMessages", - "type": 2, - "optional": false - }, - { - "name": "sessionId", - "type": 9, - "optional": false - }, - { - "name": "truncated", - "type": 25, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 2, - 75 - ] - }, - { - "kind": "primitive", - "type": "null" - }, - { - "kind": "literal", - "value": 1 - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 49, - "optional": false - }, - { - "name": "kind", - "type": 78, - "optional": false - }, - { - "name": "senderSessionId", - "type": 9, - "optional": false - }, - { - "name": "summary", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "subagent-settled" - }, - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 68, - "optional": false - }, - { - "name": "kind", - "type": 80, - "optional": false - }, - { - "name": "senderSessionId", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "agent-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "goalId", - "type": 9, - "optional": false - }, - { - "name": "kind", - "type": 82, - "optional": false - }, - { - "name": "revision", - "type": 2, - "optional": false - }, - { - "name": "round", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "goal" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 84, - "optional": false - }, - { - "name": "messageId", - "type": 9, - "optional": false - }, - { - "name": "senderId", - "type": 9, - "optional": false - }, - { - "name": "senderName", - "type": 9, - "optional": false - }, - { - "name": "teamId", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "team-message" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 86, - "optional": false - }, - { - "name": "model", - "type": 9, - "optional": false - }, - { - "name": "provider", - "type": 9, - "optional": false - }, - { - "name": "replayState", - "type": 87, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 60, - "optional": false - }, - { - "name": "plugin", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 34, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "model", - "type": 9, - "optional": false - }, - { - "name": "provider", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "session/title-llm-request" - } - ] - }, - "names": [ - "event:session/title-llm-request" - ], + "names": [], "sources": [] }, { @@ -58429,6 +81373,536 @@ "names": [], "sources": [] }, + { + "digest": "e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 4, + "optional": true + }, + { + "name": "seq", + "type": 5, + "optional": false + }, + { + "name": "time", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 34 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "llmStreamCall", + "type": 4, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": false + }, + { + "name": "shadowedRange", + "type": 31, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 32, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 33, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 7 + }, + { + "kind": "union", + "types": [ + 8, + 10, + 12, + 15, + 17, + 19, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 13, + "optional": true + }, + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 3, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "offloaded", + "type": 4, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "mediaType", + "type": 21, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": true + }, + { + "name": "originalDimensions", + "type": 26, + "optional": true + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 22, + 23, + 24, + 25 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 5, + "optional": false + }, + { + "name": "width", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 3, + "optional": false + }, + { + "name": "bytes", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "end", + "type": 5, + "optional": false + }, + { + "name": "start", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "object", + "properties": [ + { + "name": "cacheReadTokens", + "type": 5, + "optional": true + }, + { + "name": "cacheWriteTokens", + "type": 5, + "optional": true + }, + { + "name": "inputTokens", + "type": 5, + "optional": false + }, + { + "name": "outputTokens", + "type": 5, + "optional": false + }, + { + "name": "reasoningTokens", + "type": 5, + "optional": true + }, + { + "name": "totalTokens", + "type": 5, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 3, + "optional": false + }, + { + "name": "maxTokens", + "type": 5, + "optional": true + }, + { + "name": "model", + "type": 3, + "optional": false + }, + { + "name": "provider", + "type": 3, + "optional": false + }, + { + "name": "rawOutput", + "type": 6, + "optional": true + }, + { + "name": "shadowedRange", + "type": 31, + "optional": false + }, + { + "name": "shadowedSeqs", + "type": 32, + "optional": false + }, + { + "name": "shadowedTokenCount", + "type": 5, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 3, + "optional": true + }, + { + "name": "summary", + "type": 6, + "optional": false + }, + { + "name": "usage", + "type": 33, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compaction/summary" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72", "schema": { @@ -58490,9 +81964,7 @@ } ] }, - "names": [ - "event:workspace/changes" - ], + "names": [], "sources": [] }, { @@ -58554,62 +82026,7 @@ } ] }, - "names": [ - "SessionEventEnvelope[0]", - "SessionEventEnvelope[10]", - "SessionEventEnvelope[11]", - "SessionEventEnvelope[12]", - "SessionEventEnvelope[13]", - "SessionEventEnvelope[14]", - "SessionEventEnvelope[15]", - "SessionEventEnvelope[16]", - "SessionEventEnvelope[17]", - "SessionEventEnvelope[18]", - "SessionEventEnvelope[19]", - "SessionEventEnvelope[1]", - "SessionEventEnvelope[20]", - "SessionEventEnvelope[21]", - "SessionEventEnvelope[22]", - "SessionEventEnvelope[23]", - "SessionEventEnvelope[24]", - "SessionEventEnvelope[25]", - "SessionEventEnvelope[26]", - "SessionEventEnvelope[27]", - "SessionEventEnvelope[28]", - "SessionEventEnvelope[29]", - "SessionEventEnvelope[2]", - "SessionEventEnvelope[30]", - "SessionEventEnvelope[31]", - "SessionEventEnvelope[32]", - "SessionEventEnvelope[33]", - "SessionEventEnvelope[34]", - "SessionEventEnvelope[35]", - "SessionEventEnvelope[36]", - "SessionEventEnvelope[37]", - "SessionEventEnvelope[38]", - "SessionEventEnvelope[3]", - "SessionEventEnvelope[40]", - "SessionEventEnvelope[41]", - "SessionEventEnvelope[42]", - "SessionEventEnvelope[43]", - "SessionEventEnvelope[44]", - "SessionEventEnvelope[45]", - "SessionEventEnvelope[46]", - "SessionEventEnvelope[47]", - "SessionEventEnvelope[48]", - "SessionEventEnvelope[49]", - "SessionEventEnvelope[4]", - "SessionEventEnvelope[50]", - "SessionEventEnvelope[51]", - "SessionEventEnvelope[53]", - "SessionEventEnvelope[54]", - "SessionEventEnvelope[56]", - "SessionEventEnvelope[57]", - "SessionEventEnvelope[5]", - "SessionEventEnvelope[7]", - "SessionEventEnvelope[8]", - "SessionEventEnvelope[9]" - ], + "names": [], "sources": [] }, { @@ -58654,6 +82071,295 @@ "names": [], "sources": [] }, + { + "digest": "e481c46af3813e0010558e93f578b2986acd658404cec2d1679e3ac2a6c48654", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "reason", + "type": 1, + "optional": false + }, + { + "name": "turn", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 4, + 6, + 8, + 10, + 15, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "forked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 9, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 11, + "optional": false + }, + { + "name": "kind", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 12, + "optional": false + }, + { + "name": "message", + "type": 12, + "optional": false + }, + { + "name": "offloadImages", + "type": 13, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 13, + "optional": true + }, + { + "name": "requestId", + "type": 12, + "optional": true + }, + { + "name": "status", + "type": 13, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 16, + "optional": false + }, + { + "name": "reason", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 18, + 20, + 22, + 24, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 19, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 25, + "optional": false + }, + { + "name": "reason", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:297" + ] + }, { "digest": "e4c18e294232c3ba6c9f1999f168263cc55956147cfe4121720899be8e52edd1", "schema": { @@ -58700,11 +82406,9 @@ } ] }, - "names": [ - "event:tool/call.data" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:341" + "packages/core/session/src/types.ts:361" ] }, { @@ -58721,377 +82425,6 @@ "names": [], "sources": [] }, - { - "digest": "e50b0a3ed8e6c80b672e4f855c91984f03b5c3fdd5d475bf171171f391a86c83", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "role", - "type": 27, - "optional": false - }, - { - "name": "source", - "type": 28, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 2 - }, - { - "kind": "union", - "types": [ - 3, - 7, - 9, - 11, - 13, - 24 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 1, - "optional": false - }, - { - "name": "isError", - "type": 4, - "optional": true - }, - { - "name": "toolCallId", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 6, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 8, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 5, - "optional": false - }, - { - "name": "id", - "type": 5, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 14, - "optional": false - }, - { - "name": "offloaded", - "type": 22, - "optional": true - }, - { - "name": "type", - "type": 23, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 15, - "optional": false - }, - { - "name": "height", - "type": 15, - "optional": false - }, - { - "name": "mediaType", - "type": 16, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": true - }, - { - "name": "originalDimensions", - "type": 21, - "optional": true - }, - { - "name": "width", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "union", - "types": [ - 17, - 18, - 19, - 20 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 15, - "optional": false - }, - { - "name": "width", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 25, - "optional": false - }, - { - "name": "type", - "type": 26, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 5, - "optional": false - }, - { - "name": "bytes", - "type": 15, - "optional": false - }, - { - "name": "name", - "type": 5, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "literal", - "value": "assistant" - }, - { - "kind": "object", - "properties": [ - { - "name": "kind", - "type": 29, - "optional": false - }, - { - "name": "model", - "type": 5, - "optional": false - }, - { - "name": "provider", - "type": 5, - "optional": false - }, - { - "name": "replayState", - "type": 30, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "model" - }, - { - "kind": "opaque", - "reason": "unknown" - } - ] - }, - "names": [ - "packages/llm/llm/src/message.ts#AssistantMessage" - ], - "sources": [ - "packages/llm/llm/src/message.ts:148" - ] - }, - { - "digest": "e5244812c495a80c2e78ba2c2690dca5f6b58ea8d3fe5531ff94a6f9ac5e5d66", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "literal", - "value": "tool-result" - } - ] - }, - "names": [], - "sources": [] - }, { "digest": "e5d3828df1ec3e2a66879de0659e0f4866d9cfffc00825ee731a66f8a0c03d98", "schema": { @@ -59172,20 +82505,6 @@ "names": [], "sources": [] }, - { - "digest": "e654d28d1e6c471147310d2fba396d00969cfe6ed9022626d3f2c2312e0b1cbb", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "literal", - "value": "plugin" - } - ] - }, - "names": [], - "sources": [] - }, { "digest": "e72269f931559e901e5e8fe1cfcbd0669fb795f43cc038ff39fba62f60403c33", "schema": { @@ -59244,9 +82563,7 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][0]" - ], + "names": [], "sources": [ "packages/llm/llm/src/assistant-stream.ts:21" ] @@ -59346,9 +82663,7 @@ } ] }, - "names": [ - "event:hook/result" - ], + "names": [], "sources": [] }, { @@ -59393,77 +82708,6 @@ "names": [], "sources": [] }, - { - "digest": "e8d26e6993445743e6c4342c31b284c7d8f5574369abdd6021183af1a6b3538f", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "object", - "properties": [ - { - "name": "form", - "type": 1, - "optional": false - }, - { - "name": "kind", - "type": 2, - "optional": false - }, - { - "name": "plugin", - "type": 3, - "optional": false - }, - { - "name": "sections", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "snapshot" - }, - { - "kind": "literal", - "value": "plugin" - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "array", - "element": 5 - }, - { - "kind": "object", - "properties": [ - { - "name": "name", - "type": 3, - "optional": false - }, - { - "name": "text", - "type": 3, - "optional": false - } - ], - "indices": [] - } - ] - }, - "names": [ - "event:agent/inbox/spliced.data.inserted[0].source[4]", - "event:system/message.data.message.source[3]" - ], - "sources": [] - }, { "digest": "e8de0f457fed5b9ff94dc4950b59ef75fd8ba8af665cc7899485924a62653367", "schema": { @@ -59492,6 +82736,369 @@ "names": [], "sources": [] }, + { + "digest": "ea08ec1df0c33108fd03345b9af199cf04dea450aa045d3c683f216311403403", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "message", + "type": 1, + "optional": false + }, + { + "name": "teamId", + "type": 5, + "optional": false + }, + { + "name": "version", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 2, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "senderId", + "type": 5, + "optional": false + }, + { + "name": "senderName", + "type": 5, + "optional": false + }, + { + "name": "targetId", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 3 + }, + { + "kind": "union", + "types": [ + 4, + 7, + 9, + 12, + 14, + 16, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 10, + "optional": true + }, + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 5, + "optional": false + }, + { + "name": "id", + "type": 5, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 17, + "optional": false + }, + { + "name": "offloaded", + "type": 25, + "optional": true + }, + { + "name": "type", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "mediaType", + "type": 19, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": true + }, + { + "name": "originalDimensions", + "type": 24, + "optional": true + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 20, + 21, + 22, + 23 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 18, + "optional": false + }, + { + "name": "width", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 28, + "optional": false + }, + { + "name": "type", + "type": 29, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 5, + "optional": false + }, + { + "name": "bytes", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": 2 + } + ] + }, + "names": [], + "sources": [ + "packages/experimental/agent-team/src/types.ts:225" + ] + }, { "digest": "eaa71be0fbf0f702df8ea6c11d0aa2f9782263d45a10d0fb14eda662f4bfe04c", "schema": { @@ -59514,11 +83121,9 @@ } ] }, - "names": [ - "event:turn/end.data.reason[1].reason[4]" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:195" + "packages/core/session/src/types.ts:196" ] }, { @@ -59624,9 +83229,2917 @@ } ] }, - "names": [ - "event:tool/ptc-dispatch-start" - ], + "names": [], + "sources": [] + }, + { + "digest": "ec8b5ff7c77ca6893ac7ba5a0c5b2aefeb52f12c64450b7359660c2a7e8a53d7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "forked" + } + ] + }, + "names": [], + "sources": [ + "packages/core/session/src/types.ts:228" + ] + }, + { + "digest": "edbbfff1128099fda7b792c56330d2cb04debc9790988e66d1c3f4026e813e0e", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "ee577a0cc18664c9daee50e9455153321155604f8f1817362f8f4a4b6fb9e1ad", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "eef4ef54dc7a133d47448a4ee822e45a351314923ef5f66db34c8b24e4b32d80", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 26, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "sourceEventSeqs", + "type": 195, + "optional": true + }, + { + "name": "surfaceOp", + "type": 196, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 199, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "headerSeq", + "type": 2, + "optional": true + }, + { + "name": "message", + "type": 3, + "optional": false + }, + { + "name": "step", + "type": 2, + "optional": false + }, + { + "name": "turn", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "role", + "type": 31, + "optional": false + }, + { + "name": "source", + "type": 32, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 9, + 11, + 14, + 16, + 18, + 28 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 12, + "optional": true + }, + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 15, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "type", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 19, + "optional": false + }, + { + "name": "offloaded", + "type": 26, + "optional": true + }, + { + "name": "type", + "type": 27, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 20, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": true + }, + { + "name": "originalDimensions", + "type": 25, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 21, + 22, + 23, + 24 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 29, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 7, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 33, + 36, + 38, + 40, + 42, + 44, + 46, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 111, + 113, + 116, + 117, + 118, + 119, + 120, + 122, + 123, + 124, + 125, + 127, + 128, + 129, + 130, + 131, + 133, + 135, + 136, + 138, + 139, + 147, + 149, + 150, + 152, + 154, + 158, + 160, + 168, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 186, + 188, + 189, + 190, + 191, + 192, + 193, + 194 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 110, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 112, + "optional": false + }, + { + "name": "messageId", + "type": 7, + "optional": false + }, + { + "name": "senderId", + "type": 7, + "optional": false + }, + { + "name": "senderName", + "type": 7, + "optional": false + }, + { + "name": "teamId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 114, + "optional": false + }, + { + "name": "model", + "type": 7, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "replayState", + "type": 115, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 121, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 126, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 37, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 132, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 134, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 137, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 26, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 7, + "optional": true + }, + { + "name": "changes", + "type": 140, + "optional": false + }, + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 141 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 142, + "optional": false + }, + { + "name": "digest", + "type": 7, + "optional": true + }, + { + "name": "path", + "type": 7, + "optional": false + }, + { + "name": "scope", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 143, + 144, + 145 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 148, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 7, + "optional": true + }, + { + "name": "kind", + "type": 134, + "optional": false + }, + { + "name": "rpcId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 7, + "optional": false + }, + { + "name": "kind", + "type": 151, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 7, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 7, + "optional": false + }, + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 153, + "optional": false + }, + { + "name": "provider", + "type": 7, + "optional": false + }, + { + "name": "ruleId", + "type": 7, + "optional": false + }, + { + "name": "source", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 155, + "optional": false + }, + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 157, + "optional": false + }, + { + "name": "update", + "type": 26, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 7, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 47, + "optional": false + }, + { + "name": "kind", + "type": 159, + "optional": false + }, + { + "name": "name", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 161, + "optional": false + }, + { + "name": "references", + "type": 162, + "optional": false + }, + { + "name": "version", + "type": 167, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 163 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 164, + "optional": false + }, + { + "name": "compacted", + "type": 166, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 7, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 7, + "optional": false + }, + { + "name": "truncated", + "type": 166, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 165 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 171 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 7, + "optional": false + }, + { + "name": "text", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 37, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 169, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 170, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 185, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 82, + "optional": false + }, + { + "name": "kind", + "type": 187, + "optional": false + }, + { + "name": "senderSessionId", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 34, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 197, + 198 + ] + }, + { + "kind": "literal", + "value": "append" + }, + { + "kind": "object", + "properties": [ + { + "name": "endSeq", + "type": 2, + "optional": false + }, + { + "name": "op", + "type": 144, + "optional": false + }, + { + "name": "startSeq", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer/message" + } + ] + }, + "names": [], "sources": [] }, { @@ -59670,13 +86183,10 @@ } ] }, - "names": [ - "event:step/end.data", - "event:step/start.data" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:287", - "packages/core/session/src/types.ts:289" + "packages/core/session/src/types.ts:299", + "packages/core/session/src/types.ts:301" ] }, { @@ -59746,6 +86256,281 @@ "packages/api/session-controller/src/types.ts:86" ] }, + { + "digest": "f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "union", + "types": [ + 1, + 3, + 5, + 7, + 9, + 14, + 27 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "completed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "forked" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "interrupted" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 8, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "max-tokens" + }, + { + "kind": "object", + "properties": [ + { + "name": "error", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "code", + "type": 11, + "optional": false + }, + { + "name": "message", + "type": 11, + "optional": false + }, + { + "name": "offloadImages", + "type": 12, + "optional": true + }, + { + "name": "providerRetryAfterMs", + "type": 12, + "optional": true + }, + { + "name": "requestId", + "type": 11, + "optional": true + }, + { + "name": "status", + "type": 12, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "literal", + "value": "error" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 15, + "optional": false + }, + { + "name": "reason", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "aborted" + }, + { + "kind": "union", + "types": [ + 17, + 19, + 21, + 23, + 25 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "disposed" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 22, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "legacy" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 24, + "optional": false + }, + { + "name": "reason", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hook" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 26, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "parent" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "blocked" + } + ] + }, + "names": [ + "packages/core/session/src/types.ts#TurnEndReason" + ], + "sources": [ + "packages/core/session/src/types.ts:232" + ] + }, { "digest": "f1996af2602e6f62b5ab179ca5c4af00d8753938b74cc6ef102de09e99e74a7e", "schema": { @@ -59870,13 +86655,99 @@ } ] }, - "names": [ - "event:assistant/attempt.data.stream[0][3].chunk[5]" - ], + "names": [], "sources": [ - "packages/llm/llm/src/types.ts:432" + "packages/llm/llm/src/types.ts:446" ] }, + { + "digest": "f230c0b583e23b25ee0a61dbe4c05e95c1e2ae44b27939501eb9e03696f0c278", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "sections", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 5, + "optional": false + }, + { + "name": "text", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f29d63336e8266d80dd7baeab219436db86341304f6be1cd0edb36f5134c4a47", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "f2da0f27c1e6add59982c37b15e4a4912c5b33466859cce3b13d503600e24aef", "schema": { @@ -59937,7 +86808,7 @@ "packages/llm/llm/src/types.ts#FileBlock" ], "sources": [ - "packages/llm/llm/src/types.ts:97" + "packages/llm/llm/src/types.ts:98" ] }, { @@ -59955,9 +86826,34 @@ "packages/llm/llm/src/types.ts#SystemPromptUpdate" ], "sources": [ - "packages/llm/llm/src/types.ts:383" + "packages/llm/llm/src/types.ts:397" ] }, + { + "digest": "f4a66f654996c093aae700ea4c434ff2ee3569fea9c0e5813ccf6afdccabd163", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "f56c5b59ca0161310c338d31dd16cf14287ccd602ff4181058df178c1c286d7f", "schema": { @@ -60099,35 +86995,7 @@ ] }, { - "digest": "f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "literal", - "value": "plan/mode" - } - ] - }, - "names": [], - "sources": [] - }, - { - "digest": "f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "literal", - "value": "replace" - } - ] - }, - "names": [], - "sources": [] - }, - { - "digest": "f6f3f30109e9008fccf7da2a3268a63da8646b59dd7cf7b75bcd9cf08ac08a59", + "digest": "f61313bd96ed95b72eb16a4a5a77ad94a0da1756d428d3d660ff6e23c9e6342b", "schema": { "root": 0, "nodes": [ @@ -60135,102 +87003,66 @@ "kind": "object", "properties": [ { - "name": "data", + "name": "content", "type": 1, "optional": false }, { - "name": "ignorable", + "name": "id", "type": 4, - "optional": true - }, - { - "name": "seq", - "type": 5, "optional": false }, { - "name": "time", - "type": 5, + "name": "role", + "type": 29, "optional": false }, { - "name": "type", - "type": 33, - "optional": false + "name": "source", + "type": 30, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } } ], "indices": [] }, + { + "kind": "array", + "element": 2 + }, { "kind": "union", "types": [ - 2, - 32 + 3, + 6, + 8, + 11, + 13, + 15, + 26 ] }, { "kind": "object", "properties": [ { - "name": "compactionId", - "type": 3, - "optional": false - }, - { - "name": "llmStreamCall", + "name": "text", "type": 4, "optional": false }, { - "name": "maxTokens", - "type": 5, - "optional": true - }, - { - "name": "model", - "type": 3, - "optional": false - }, - { - "name": "provider", - "type": 3, - "optional": false - }, - { - "name": "rawOutput", - "type": 6, - "optional": false - }, - { - "name": "shadowedRange", - "type": 29, - "optional": false - }, - { - "name": "shadowedSeqs", - "type": 30, - "optional": false - }, - { - "name": "shadowedTokenCount", + "name": "type", "type": 5, "optional": false - }, - { - "name": "sourceCommandId", - "type": 3, - "optional": true - }, - { - "name": "summary", - "type": 6, - "optional": false - }, - { - "name": "usage", - "type": 31, - "optional": true } ], "indices": [] @@ -60239,79 +87071,6 @@ "kind": "primitive", "type": "string" }, - { - "kind": "literal", - "value": true - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 7 - }, - { - "kind": "union", - "types": [ - 8, - 11, - 13, - 15, - 17, - 26 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 6, - "optional": false - }, - { - "name": "isError", - "type": 9, - "optional": true - }, - { - "name": "toolCallId", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 10, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 3, - "optional": false - }, - { - "name": "type", - "type": 12, - "optional": false - } - ], - "indices": [] - }, { "kind": "literal", "value": "reasoning" @@ -60321,12 +87080,12 @@ "properties": [ { "name": "text", - "type": 3, + "type": 4, "optional": false }, { "name": "type", - "type": 14, + "type": 7, "optional": false } ], @@ -60340,23 +87099,72 @@ "kind": "object", "properties": [ { - "name": "arguments", - "type": 3, - "optional": false + "name": "tool", + "type": 9, + "optional": true }, { - "name": "id", - "type": 3, - "optional": false - }, - { - "name": "name", - "type": 3, + "name": "toolName", + "type": 4, "optional": false }, { "name": "type", - "type": 16, + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 14, "optional": false } ], @@ -60371,12 +87179,12 @@ "properties": [ { "name": "attachment", - "type": 18, + "type": 16, "optional": false }, { "name": "offloaded", - "type": 4, + "type": 24, "optional": true }, { @@ -60392,54 +87200,54 @@ "properties": [ { "name": "attachmentId", - "type": 3, + "type": 4, "optional": false }, { "name": "bytes", - "type": 5, + "type": 17, "optional": false }, { "name": "height", - "type": 5, + "type": 17, "optional": false }, { "name": "mediaType", - "type": 19, + "type": 18, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": true }, { "name": "originalDimensions", - "type": 24, + "type": 23, "optional": true }, { "name": "width", - "type": 5, + "type": 17, "optional": false } ], "indices": [] }, { - "kind": "union", - "types": [ - 20, - 21, - 22, - 23 - ] + "kind": "primitive", + "type": "number" }, { - "kind": "literal", - "value": "image/gif" + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] }, { "kind": "literal", @@ -60453,22 +87261,30 @@ "kind": "literal", "value": "image/webp" }, + { + "kind": "literal", + "value": "image/gif" + }, { "kind": "object", "properties": [ { "name": "height", - "type": 5, + "type": 17, "optional": false }, { "name": "width", - "type": 5, + "type": 17, "optional": false } ], "indices": [] }, + { + "kind": "literal", + "value": true + }, { "kind": "literal", "value": "image" @@ -60494,17 +87310,17 @@ "properties": [ { "name": "attachmentId", - "type": 3, + "type": 4, "optional": false }, { "name": "bytes", - "type": 5, + "type": 17, "optional": false }, { "name": "name", - "type": 3, + "type": 4, "optional": false } ], @@ -60514,17 +87330,1392 @@ "kind": "literal", "value": "file" }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 31, + 34, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 60, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 104, + 106, + 109, + 110, + 111, + 112, + 113, + 115, + 116, + 117, + 118, + 120, + 121, + 122, + 123, + 124, + 126, + 128, + 130, + 131, + 132, + 140, + 142, + 143, + 145, + 147, + 151, + 153, + 161, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 179, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192 + ] + }, { "kind": "object", "properties": [ { - "name": "end", - "type": 5, + "name": "form", + "type": 32, "optional": false }, { - "name": "start", - "type": 5, + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 103, + "optional": false + }, + { + "name": "revision", + "type": 17, + "optional": false + }, + { + "name": "round", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 105, + "optional": false + }, + { + "name": "messageId", + "type": 4, + "optional": false + }, + { + "name": "senderId", + "type": 4, + "optional": false + }, + { + "name": "senderName", + "type": 4, + "optional": false + }, + { + "name": "teamId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 107, + "optional": false + }, + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "replayState", + "type": 108, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 36, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 38, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 40, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 114, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 119, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 125, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 127, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 129, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 24, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 4, + "optional": true + }, + { + "name": "changes", + "type": 133, + "optional": false + }, + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 139, "optional": false } ], @@ -60532,40 +88723,95 @@ }, { "kind": "array", - "element": 5 + "element": 134 }, { "kind": "object", "properties": [ { - "name": "cacheReadTokens", - "type": 5, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 5, - "optional": true - }, - { - "name": "inputTokens", - "type": 5, + "name": "action", + "type": 135, "optional": false }, { - "name": "outputTokens", - "type": 5, + "name": "digest", + "type": 4, + "optional": true + }, + { + "name": "path", + "type": 4, "optional": false }, { - "name": "reasoningTokens", - "type": 5, + "name": "scope", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 136, + 137, + 138 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 4, + "optional": false + }, + { + "name": "kind", + "type": 141, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 4, "optional": true }, { - "name": "totalTokens", - "type": 5, - "optional": true + "name": "kind", + "type": 127, + "optional": false + }, + { + "name": "rpcId", + "type": 4, + "optional": false } ], "indices": [] @@ -60575,57 +88821,17 @@ "properties": [ { "name": "compactionId", - "type": 3, + "type": 4, "optional": false }, { - "name": "maxTokens", - "type": 5, - "optional": true - }, - { - "name": "model", - "type": 3, - "optional": false - }, - { - "name": "provider", - "type": 3, - "optional": false - }, - { - "name": "rawOutput", - "type": 6, - "optional": true - }, - { - "name": "shadowedRange", - "type": 29, - "optional": false - }, - { - "name": "shadowedSeqs", - "type": 30, - "optional": false - }, - { - "name": "shadowedTokenCount", - "type": 5, + "name": "kind", + "type": 144, "optional": false }, { "name": "sourceCommandId", - "type": 3, - "optional": true - }, - { - "name": "summary", - "type": 6, - "optional": false - }, - { - "name": "usage", - "type": 31, + "type": 4, "optional": true } ], @@ -60633,13 +88839,1022 @@ }, { "kind": "literal", - "value": "compaction/summary" + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 4, + "optional": false + }, + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 146, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "ruleId", + "type": 4, + "optional": false + }, + { + "name": "source", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 148, + "optional": false + }, + { + "name": "form", + "type": 89, + "optional": false + }, + { + "name": "kind", + "type": 150, + "optional": false + }, + { + "name": "update", + "type": 24, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 149 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 35, + "optional": false + }, + { + "name": "kind", + "type": 152, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 61, + "optional": false + }, + { + "name": "kind", + "type": 154, + "optional": false + }, + { + "name": "references", + "type": 155, + "optional": false + }, + { + "name": "version", + "type": 160, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 156 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 17, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 157, + "optional": false + }, + { + "name": "compacted", + "type": 159, + "optional": false + }, + { + "name": "inputIndex", + "type": 17, + "optional": false + }, + { + "name": "label", + "type": 4, + "optional": false + }, + { + "name": "omittedBytes", + "type": 17, + "optional": false + }, + { + "name": "omittedMessages", + "type": 17, + "optional": false + }, + { + "name": "originalMessages", + "type": 17, + "optional": false + }, + { + "name": "retainedMessages", + "type": 17, + "optional": false + }, + { + "name": "sessionId", + "type": 4, + "optional": false + }, + { + "name": "truncated", + "type": 159, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 17, + 158 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 164 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "text", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 162, + "optional": false + }, + { + "name": "kind", + "type": 33, + "optional": false + }, + { + "name": "sections", + "type": 163, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 178, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 75, + "optional": false + }, + { + "name": "kind", + "type": 180, + "optional": false + }, + { + "name": "senderSessionId", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 36, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 38, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 40, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 46, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 32, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 4, + "optional": false + } + ], + "indices": [] } ] }, "names": [ - "event:compaction/summary" + "packages/llm/llm/src/message.ts#DeveloperMessage" ], + "sources": [ + "packages/llm/llm/src/message.ts:157" + ] + }, + { + "digest": "f6329fb30c7ea8013e8975ca5e78284fb7685cc6bd620e8aa4e9a99bc81d45eb", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "plan-mode" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f634871d1e18b1eb199497ac8ab72d3964f48d03fbf611dc7521a1970cf429d9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "plan/mode" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f6605d6c57933aeaaf10911b5fbd6c61e655baa181af7192d3240f49d255b90d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "model-selection" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f68c335306535a001127dae6685ece493a0ee7f4e2a851197b6054d8a9ff7394", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "user-approval" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f6afe41e3926f422fe849debe90819fddd739f0f59e20be9c71018b9554a7f09", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "time-context" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "literal", + "value": "replace" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "f7283223aacdc39b0adca728c8cbd4c090a20006a6fecec74421c30e943b489c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 1, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + } + ] + }, + "names": [], "sources": [] }, { @@ -60692,15 +89907,46 @@ } ] }, - "names": [ - "event:turn/start.data", - "event:workspace/changes.data" - ], + "names": [], "sources": [ - "packages/core/session/src/types.ts:276", + "packages/core/session/src/types.ts:288", "packages/deliverables/workspace-changes/src/types.ts:106" ] }, + { + "digest": "f97f47b0eb87905ed77cc27c5e4ed75ef805cb372c98905253709de1aab9b63c", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "tmux-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "f9cfc89e8fe085b4fcc9cd32b74b6f103608c54d7d8cd97b47c01de34f252ba3", "schema": { @@ -60715,6 +89961,3306 @@ "names": [], "sources": [] }, + { + "digest": "fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 1, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "role", + "type": 29, + "optional": false + }, + { + "name": "source", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "union", + "types": [ + 3, + 6, + 8, + 11, + 13, + 15, + 26 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 5, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 9, + "optional": true + }, + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 12, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 4, + "optional": false + }, + { + "name": "id", + "type": 4, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + }, + { + "name": "type", + "type": 14, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 16, + "optional": false + }, + { + "name": "offloaded", + "type": 24, + "optional": true + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "mediaType", + "type": 18, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": true + }, + { + "name": "originalDimensions", + "type": 23, + "optional": true + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 19, + 20, + 21, + 22 + ] + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 17, + "optional": false + }, + { + "name": "width", + "type": 17, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 27, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 4, + "optional": false + }, + { + "name": "bytes", + "type": 17, + "optional": false + }, + { + "name": "name", + "type": 4, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 31, + "optional": false + }, + { + "name": "model", + "type": 4, + "optional": false + }, + { + "name": "provider", + "type": 4, + "optional": false + }, + { + "name": "replayState", + "type": 32, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + } + ] + }, + "names": [ + "packages/llm/llm/src/message.ts#AssistantMessage" + ], + "sources": [ + "packages/llm/llm/src/message.ts:167" + ] + }, + { + "digest": "fa8f7d3ebf08a76c7f7a8b0781873c4d819b964da5dbb52cd3cdfa5da34f452d", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "data", + "type": 1, + "optional": false + }, + { + "name": "ignorable", + "type": 29, + "optional": true + }, + { + "name": "seq", + "type": 2, + "optional": false + }, + { + "name": "time", + "type": 2, + "optional": false + }, + { + "name": "type", + "type": 205, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "maxTokens", + "type": 2, + "optional": false + }, + { + "name": "messageSeqs", + "type": 3, + "optional": false + }, + { + "name": "messages", + "type": 4, + "optional": false + }, + { + "name": "route", + "type": 204, + "optional": false + }, + { + "name": "system", + "type": 10, + "optional": false + }, + { + "name": "titleProvider", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "array", + "element": 2 + }, + { + "kind": "array", + "element": 5 + }, + { + "kind": "union", + "types": [ + 6, + 37, + 199, + 200, + 202 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "isError", + "type": 34, + "optional": true + }, + { + "name": "role", + "type": 35, + "optional": false + }, + { + "name": "source", + "type": 36, + "optional": false + }, + { + "name": "toolCallId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 8 + }, + { + "kind": "union", + "types": [ + 9, + 12, + 14, + 17, + 19, + 21, + 31 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 11, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 13, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 15, + "optional": true + }, + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 16, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 10, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "type", + "type": 20, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 22, + "optional": false + }, + { + "name": "offloaded", + "type": 29, + "optional": true + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 10, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "mediaType", + "type": 23, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": true + }, + { + "name": "originalDimensions", + "type": 28, + "optional": true + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 24, + 25, + 26, + 27 + ] + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 2, + "optional": false + }, + { + "name": "width", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 32, + "optional": false + }, + { + "name": "type", + "type": 33, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 10, + "optional": false + }, + { + "name": "bytes", + "type": 2, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 35, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 38, + "optional": false + }, + { + "name": "source", + "type": 39, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 36, + 40, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 70, + 72, + 74, + 76, + 78, + 80, + 85, + 87, + 95, + 100, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 142, + 143, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 174, + 175, + 177, + 180, + 181, + 182, + 183, + 184, + 186, + 187, + 188, + 189, + 190, + 192, + 193, + 194, + 195, + 196, + 198 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 46, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 29, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 10, + "optional": true + }, + { + "name": "changes", + "type": 62, + "optional": false + }, + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 69, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 63 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 64, + "optional": false + }, + { + "name": "digest", + "type": 10, + "optional": true + }, + { + "name": "path", + "type": 10, + "optional": false + }, + { + "name": "scope", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 65, + 66, + 67 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 10, + "optional": true + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "rpcId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 73, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 10, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 10, + "optional": false + }, + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 77, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + }, + { + "name": "ruleId", + "type": 10, + "optional": false + }, + { + "name": "source", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 81, + "optional": false + }, + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 84, + "optional": false + }, + { + "name": "update", + "type": 29, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 82 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 86, + "optional": false + }, + { + "name": "name", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 89, + "optional": false + }, + { + "name": "references", + "type": 90, + "optional": false + }, + { + "name": "version", + "type": 94, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 91 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 2, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 92, + "optional": false + }, + { + "name": "compacted", + "type": 34, + "optional": false + }, + { + "name": "inputIndex", + "type": 2, + "optional": false + }, + { + "name": "label", + "type": 10, + "optional": false + }, + { + "name": "omittedBytes", + "type": 2, + "optional": false + }, + { + "name": "omittedMessages", + "type": 2, + "optional": false + }, + { + "name": "originalMessages", + "type": 2, + "optional": false + }, + { + "name": "retainedMessages", + "type": 2, + "optional": false + }, + { + "name": "sessionId", + "type": 10, + "optional": false + }, + { + "name": "truncated", + "type": 34, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 2, + 93 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "array", + "element": 99 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 10, + "optional": false + }, + { + "name": "text", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 96, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + }, + { + "name": "sections", + "type": 98, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 141, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 88, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 144, + "optional": false + }, + { + "name": "kind", + "type": 162, + "optional": false + }, + { + "name": "senderSessionId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 44, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 83, + "optional": false + }, + { + "name": "kind", + "type": 48, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 10, + "optional": false + }, + { + "name": "kind", + "type": 173, + "optional": false + }, + { + "name": "revision", + "type": 2, + "optional": false + }, + { + "name": "round", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 176, + "optional": false + }, + { + "name": "messageId", + "type": 10, + "optional": false + }, + { + "name": "senderId", + "type": 10, + "optional": false + }, + { + "name": "senderName", + "type": 10, + "optional": false + }, + { + "name": "teamId", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 178, + "optional": false + }, + { + "name": "model", + "type": 10, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + }, + { + "name": "replayState", + "type": 179, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 101, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 42, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 50, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 185, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 52, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 41, + "optional": false + }, + { + "name": "kind", + "type": 101, + "optional": false + }, + { + "name": "summary", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 54, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 56, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 191, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 58, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 60, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 75, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 197, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 71, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 71, + "optional": false + }, + { + "name": "source", + "type": 39, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 201, + "optional": false + }, + { + "name": "source", + "type": 177, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 7, + "optional": false + }, + { + "name": "id", + "type": 10, + "optional": false + }, + { + "name": "role", + "type": 203, + "optional": false + }, + { + "name": "source", + "type": 190, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system" + }, + { + "kind": "object", + "properties": [ + { + "name": "model", + "type": 10, + "optional": false + }, + { + "name": "provider", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "session/title-llm-request" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "fab2bb09bc5e3b9db0685e8f5500b029af1a2b33e70bc703c1d5d0f596fbc1fd", "schema": { @@ -60881,6 +93427,2890 @@ "packages/skill/tool-skill/src/index.ts:34" ] }, + { + "digest": "fc8242857caf7450d7f68a1f509dce83e237bd21571666006895124cb2246a83", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "array", + "element": 1 + }, + { + "kind": "union", + "types": [ + 2, + 34, + 196, + 197, + 199 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "isError", + "type": 31, + "optional": true + }, + { + "name": "role", + "type": 32, + "optional": false + }, + { + "name": "source", + "type": 33, + "optional": false + }, + { + "name": "toolCallId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 4 + }, + { + "kind": "union", + "types": [ + 5, + 8, + 19, + 22, + 24, + 26, + 29 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "arguments", + "type": 6, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 7, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "string" + }, + { + "kind": "literal", + "value": "tool-call" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 9, + "optional": false + }, + { + "name": "offloaded", + "type": 17, + "optional": true + }, + { + "name": "type", + "type": 18, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "mediaType", + "type": 11, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": true + }, + { + "name": "originalDimensions", + "type": 16, + "optional": true + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "number" + }, + { + "kind": "union", + "types": [ + 12, + 13, + 14, + 15 + ] + }, + { + "kind": "literal", + "value": "image/jpeg" + }, + { + "kind": "literal", + "value": "image/gif" + }, + { + "kind": "literal", + "value": "image/png" + }, + { + "kind": "literal", + "value": "image/webp" + }, + { + "kind": "object", + "properties": [ + { + "name": "height", + "type": 10, + "optional": false + }, + { + "name": "width", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "literal", + "value": "image" + }, + { + "kind": "object", + "properties": [ + { + "name": "attachment", + "type": 20, + "optional": false + }, + { + "name": "type", + "type": 21, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "attachmentId", + "type": 6, + "optional": false + }, + { + "name": "bytes", + "type": 10, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "file" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 23, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "reasoning" + }, + { + "kind": "object", + "properties": [ + { + "name": "text", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 25, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "text" + }, + { + "kind": "object", + "properties": [ + { + "name": "tool", + "type": 27, + "optional": true + }, + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 28, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "primitive", + "type": "never" + }, + { + "kind": "literal", + "value": "tool-addition" + }, + { + "kind": "object", + "properties": [ + { + "name": "toolName", + "type": 6, + "optional": false + }, + { + "name": "type", + "type": 30, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-removal" + }, + { + "kind": "primitive", + "type": "boolean" + }, + { + "kind": "literal", + "value": "tool" + }, + { + "kind": "object", + "properties": [ + { + "name": "callId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 32, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 35, + "optional": false + }, + { + "name": "source", + "type": 36, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.developer-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "developer" + }, + { + "kind": "union", + "types": [ + 33, + 37, + 40, + 42, + 44, + 46, + 48, + 56, + 58, + 60, + 62, + 65, + 70, + 72, + 80, + 84, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 94, + 96, + 98, + 100, + 101, + 103, + 105, + 107, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 166, + 167, + 169, + 172, + 173, + 174, + 175, + 176, + 178, + 179, + 180, + 181, + 182, + 184, + 185, + 186, + 187, + 188, + 190, + 191, + 192, + 193, + 195 + ] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "instructions" + }, + { + "kind": "literal", + "value": "hooks-claude-code" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "hooks-codex" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model-selection" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "plan-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "object", + "properties": [ + { + "name": "baseline", + "type": 17, + "optional": true + }, + { + "name": "baselineIdentity", + "type": 6, + "optional": true + }, + { + "name": "changes", + "type": 49, + "optional": false + }, + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 55, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 50 + }, + { + "kind": "object", + "properties": [ + { + "name": "action", + "type": 51, + "optional": false + }, + { + "name": "digest", + "type": 6, + "optional": true + }, + { + "name": "path", + "type": 6, + "optional": false + }, + { + "name": "scope", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 52, + 53, + 54 + ] + }, + { + "kind": "literal", + "value": "remove" + }, + { + "kind": "literal", + "value": "replace" + }, + { + "kind": "literal", + "value": "set" + }, + { + "kind": "literal", + "value": "agent-instructions" + }, + { + "kind": "object", + "properties": [ + { + "name": "clientTimeZone", + "type": 6, + "optional": true + }, + { + "name": "kind", + "type": 57, + "optional": false + }, + { + "name": "rpcId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user" + }, + { + "kind": "object", + "properties": [ + { + "name": "compactionId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 59, + "optional": false + }, + { + "name": "sourceCommandId", + "type": 6, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "compact-checkpoint" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "runtime-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "deliveryId", + "type": 6, + "optional": false + }, + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 64, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "ruleId", + "type": 6, + "optional": false + }, + { + "name": "source", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "webhook" + }, + { + "kind": "object", + "properties": [ + { + "name": "entries", + "type": 66, + "optional": false + }, + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 69, + "optional": false + }, + { + "name": "update", + "type": 17, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "array", + "element": 67 + }, + { + "kind": "object", + "properties": [ + { + "name": "description", + "type": 6, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "catalog" + }, + { + "kind": "literal", + "value": "skill-catalog" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 71, + "optional": false + }, + { + "name": "name", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "skill-invocation" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 74, + "optional": false + }, + { + "name": "references", + "type": 75, + "optional": false + }, + { + "name": "version", + "type": 79, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "session-reference" + }, + { + "kind": "array", + "element": 76 + }, + { + "kind": "object", + "properties": [ + { + "name": "capturedFormatVersion", + "type": 10, + "optional": true + }, + { + "name": "capturedThroughSeq", + "type": 77, + "optional": false + }, + { + "name": "compacted", + "type": 31, + "optional": false + }, + { + "name": "inputIndex", + "type": 10, + "optional": false + }, + { + "name": "label", + "type": 6, + "optional": false + }, + { + "name": "omittedBytes", + "type": 10, + "optional": false + }, + { + "name": "omittedMessages", + "type": 10, + "optional": false + }, + { + "name": "originalMessages", + "type": 10, + "optional": false + }, + { + "name": "retainedMessages", + "type": 10, + "optional": false + }, + { + "name": "sessionId", + "type": 6, + "optional": false + }, + { + "name": "truncated", + "type": 31, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "union", + "types": [ + 10, + 78 + ] + }, + { + "kind": "primitive", + "type": "null" + }, + { + "kind": "literal", + "value": 1 + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "snapshot" + }, + { + "kind": "array", + "element": 83 + }, + { + "kind": "object", + "properties": [ + { + "name": "name", + "type": 6, + "optional": false + }, + { + "name": "text", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 85, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "schedule" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 85, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 93, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "time-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tmux-context" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-jobs" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 93, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "user-approval" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 81, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + }, + { + "name": "sections", + "type": 82, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "dsh-session-title-llm" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 106, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "subagent-settled" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 109, + "optional": false + }, + { + "name": "senderSessionId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "relay" + }, + { + "kind": "literal", + "value": "agent-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 38, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 85, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 85, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 93, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 73, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 93, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 85, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 93, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 108, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 85, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 93, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 95, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 68, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "goalId", + "type": 6, + "optional": false + }, + { + "name": "kind", + "type": 165, + "optional": false + }, + { + "name": "revision", + "type": 10, + "optional": false + }, + { + "name": "round", + "type": 10, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "goal" + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 99, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 168, + "optional": false + }, + { + "name": "messageId", + "type": 6, + "optional": false + }, + { + "name": "senderId", + "type": 6, + "optional": false + }, + { + "name": "senderName", + "type": 6, + "optional": false + }, + { + "name": "teamId", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "team-message" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 170, + "optional": false + }, + { + "name": "model", + "type": 6, + "optional": false + }, + { + "name": "provider", + "type": 6, + "optional": false + }, + { + "name": "replayState", + "type": 171, + "optional": true + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "model" + }, + { + "kind": "opaque", + "reason": "unknown" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 39, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 41, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 43, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 45, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 177, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "ptc-mode" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 47, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 102, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 61, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 85, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 183, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system-prompt" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 93, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 95, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 97, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 99, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 189, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "tool-registry" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 57, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 102, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 63, + "optional": false + }, + { + "name": "kind", + "type": 104, + "optional": false + }, + { + "name": "summary", + "type": 6, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 194, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "cordis-host-runner" + }, + { + "kind": "object", + "properties": [ + { + "name": "kind", + "type": 104, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 57, + "optional": false + }, + { + "name": "source", + "type": 36, + "optional": false, + "compatibility": { + "version": 1, + "policy": "session-source-attribution", + "binding": "session.user-message.source", + "discriminator": "kind", + "unknownKinds": "preserve", + "attributionKinds": [ + "tmux-context" + ] + } + } + ], + "indices": [] + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 198, + "optional": false + }, + { + "name": "source", + "type": 169, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "assistant" + }, + { + "kind": "object", + "properties": [ + { + "name": "content", + "type": 3, + "optional": false + }, + { + "name": "id", + "type": 6, + "optional": false + }, + { + "name": "role", + "type": 200, + "optional": false + }, + { + "name": "source", + "type": 182, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "system" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fcf427290c6213c2a7feb57492d832ce324f5b9737a759f424dab69e6bd101a0", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "primitive", + "type": "never" + } + ] + }, + "names": [], + "sources": [] + }, + { + "digest": "fcf81d3c58c13593bf2594e342e31734f4ab2d24938dc610875194c6079749c7", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "recall" + }, + { + "kind": "literal", + "value": "tmux-context" + } + ] + }, + "names": [], + "sources": [] + }, { "digest": "fd0d91a1f9dd2efb8959bdf5e07f8f0a98b1cdfa38ce8d4732ebde0b44c3abd4", "schema": { @@ -60908,9 +96338,50 @@ } ] }, - "names": [ - "event:todo/write.data.todos[0].status" - ], + "names": [], + "sources": [] + }, + { + "digest": "fe1a7acdeed4d0f5ab483396eaa5b3dc97263b7c10eb4da2f0028cb01728bfc9", + "schema": { + "root": 0, + "nodes": [ + { + "kind": "object", + "properties": [ + { + "name": "form", + "type": 1, + "optional": false + }, + { + "name": "kind", + "type": 2, + "optional": false + }, + { + "name": "summary", + "type": 3, + "optional": false + } + ], + "indices": [] + }, + { + "kind": "literal", + "value": "notice" + }, + { + "kind": "literal", + "value": "repeat-tool-reminder" + }, + { + "kind": "primitive", + "type": "string" + } + ] + }, + "names": [], "sources": [] }, { @@ -60927,487 +96398,6 @@ "names": [], "sources": [] }, - { - "digest": "feb329074f0206ecc06d8a1aa0a0b3e2f47fd27524ba020fbc849ba63e938896", - "schema": { - "root": 0, - "nodes": [ - { - "kind": "union", - "types": [ - 1, - 31 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "compactionId", - "type": 2, - "optional": false - }, - { - "name": "llmStreamCall", - "type": 3, - "optional": false - }, - { - "name": "maxTokens", - "type": 4, - "optional": true - }, - { - "name": "model", - "type": 2, - "optional": false - }, - { - "name": "provider", - "type": 2, - "optional": false - }, - { - "name": "rawOutput", - "type": 5, - "optional": false - }, - { - "name": "shadowedRange", - "type": 28, - "optional": false - }, - { - "name": "shadowedSeqs", - "type": 29, - "optional": false - }, - { - "name": "shadowedTokenCount", - "type": 4, - "optional": false - }, - { - "name": "sourceCommandId", - "type": 2, - "optional": true - }, - { - "name": "summary", - "type": 5, - "optional": false - }, - { - "name": "usage", - "type": 30, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "string" - }, - { - "kind": "literal", - "value": true - }, - { - "kind": "primitive", - "type": "number" - }, - { - "kind": "array", - "element": 6 - }, - { - "kind": "union", - "types": [ - 7, - 10, - 12, - 14, - 16, - 25 - ] - }, - { - "kind": "object", - "properties": [ - { - "name": "content", - "type": 5, - "optional": false - }, - { - "name": "isError", - "type": 8, - "optional": true - }, - { - "name": "toolCallId", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 9, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "primitive", - "type": "boolean" - }, - { - "kind": "literal", - "value": "tool-result" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 11, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "reasoning" - }, - { - "kind": "object", - "properties": [ - { - "name": "text", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 13, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "text" - }, - { - "kind": "object", - "properties": [ - { - "name": "arguments", - "type": 2, - "optional": false - }, - { - "name": "id", - "type": 2, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - }, - { - "name": "type", - "type": 15, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "tool-call" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 17, - "optional": false - }, - { - "name": "offloaded", - "type": 3, - "optional": true - }, - { - "name": "type", - "type": 24, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 4, - "optional": false - }, - { - "name": "height", - "type": 4, - "optional": false - }, - { - "name": "mediaType", - "type": 18, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": true - }, - { - "name": "originalDimensions", - "type": 23, - "optional": true - }, - { - "name": "width", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "union", - "types": [ - 19, - 20, - 21, - 22 - ] - }, - { - "kind": "literal", - "value": "image/gif" - }, - { - "kind": "literal", - "value": "image/jpeg" - }, - { - "kind": "literal", - "value": "image/png" - }, - { - "kind": "literal", - "value": "image/webp" - }, - { - "kind": "object", - "properties": [ - { - "name": "height", - "type": 4, - "optional": false - }, - { - "name": "width", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "image" - }, - { - "kind": "object", - "properties": [ - { - "name": "attachment", - "type": 26, - "optional": false - }, - { - "name": "type", - "type": 27, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "attachmentId", - "type": 2, - "optional": false - }, - { - "name": "bytes", - "type": 4, - "optional": false - }, - { - "name": "name", - "type": 2, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "literal", - "value": "file" - }, - { - "kind": "object", - "properties": [ - { - "name": "end", - "type": 4, - "optional": false - }, - { - "name": "start", - "type": 4, - "optional": false - } - ], - "indices": [] - }, - { - "kind": "array", - "element": 4 - }, - { - "kind": "object", - "properties": [ - { - "name": "cacheReadTokens", - "type": 4, - "optional": true - }, - { - "name": "cacheWriteTokens", - "type": 4, - "optional": true - }, - { - "name": "inputTokens", - "type": 4, - "optional": false - }, - { - "name": "outputTokens", - "type": 4, - "optional": false - }, - { - "name": "reasoningTokens", - "type": 4, - "optional": true - }, - { - "name": "totalTokens", - "type": 4, - "optional": true - } - ], - "indices": [] - }, - { - "kind": "object", - "properties": [ - { - "name": "compactionId", - "type": 2, - "optional": false - }, - { - "name": "maxTokens", - "type": 4, - "optional": true - }, - { - "name": "model", - "type": 2, - "optional": false - }, - { - "name": "provider", - "type": 2, - "optional": false - }, - { - "name": "rawOutput", - "type": 5, - "optional": true - }, - { - "name": "shadowedRange", - "type": 28, - "optional": false - }, - { - "name": "shadowedSeqs", - "type": 29, - "optional": false - }, - { - "name": "shadowedTokenCount", - "type": 4, - "optional": false - }, - { - "name": "sourceCommandId", - "type": 2, - "optional": true - }, - { - "name": "summary", - "type": 5, - "optional": false - }, - { - "name": "usage", - "type": 30, - "optional": true - } - ], - "indices": [] - } - ] - }, - "names": [ - "event:compaction/summary.data" - ], - "sources": [] - }, { "digest": "fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394", "schema": { @@ -61459,7 +96449,7 @@ "packages/llm/llm/src/types.ts#TokenUsage" ], "sources": [ - "packages/llm/llm/src/types.ts:162" + "packages/llm/llm/src/types.ts:176" ] }, { diff --git a/docs/session-format-status.i18n.yaml b/docs/session-format-status.i18n.yaml index 2b9682532a..00b72e5e97 100644 --- a/docs/session-format-status.i18n.yaml +++ b/docs/session-format-status.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/session-format-status.md -session-format-status.md: eb48234963b866d1bc95bb7c3c72753d54dd93aa -session-format-status.zh.md: a54e98b32b37a723ef44c90d2f4983ea3615fc03 +session-format-status.md: 9df313da2fad277254f464a8bdf6a6c8b541aab1 +session-format-status.zh.md: 31e1710632b07a1f64a5bc528bf0827c5af47af9 diff --git a/docs/session-format-status.md b/docs/session-format-status.md index eb48234963..9df313da2f 100644 --- a/docs/session-format-status.md +++ b/docs/session-format-status.md @@ -4,11 +4,12 @@ English | [中文](session-format-status.zh.md) ## Summary -Use this reference to distinguish the checkout’s Session writer version from the latest published Session format. The code constant owns the writer version; the release record below owns the latest released format and its publication evidence. Other documentation links here instead of restating which version is current, next, or unreleased. +Use this reference to distinguish the checkout writer, the accepted compatibility baseline, and the latest published Session format. The code constant owns the writer; the finalization and release records below separately identify accepted history and publication evidence. Other documentation links here instead of restating those values. ## Table of Contents - [Sources of truth](#sources-of-truth) +- [Finalization record](#finalization-record) - [Release record](#release-record) - [Updating the record](#updating-the-record) - [Dev Note](#dev-note) @@ -18,12 +19,25 @@ Use this reference to distinguish the checkout’s Session writer version from t - **Checkout writer:** `SESSION_FORMAT_VERSION` in [core Session types](../packages/core/session/src/types.ts) is the only hand-maintained current-writer number in code. The [catalog generator](../scripts/gen-session-format-catalog.ts) derives codec ordering and checks that adjacent migrations reach it. A package version, codec export name, fixture filename, or projection-cache version is not the writer authority. - **Latest released format:** `latestReleasedVersion` in the following record identifies the published Session format. `evidenceTag` names a published product release whose tagged writer has that value; it need not be the first release carrying the format. The bilingual copy is checked against the same record, not maintained as a separate decision. -- **Release status:** compare the writer constant with the verified release record. Equality means the writer format has shipped. A greater writer version is a development target beyond the recorded release. When comparing an older checkout against a newer branch’s verified record, a lower writer version identifies an older writer format; the local consistency gate rejects that ordering within one checkout. No separate released boolean is maintained. Before declaring a greater version unreleased, verify that no published release has advanced the record. +- **Release status:** compare the writer constant with the verified release record. Equality means the writer format has shipped. A greater writer version is not yet recorded as published; its finalization record independently identifies the accepted compatibility baseline. When comparing an older checkout against a newer branch’s verified record, a lower writer version identifies an older writer format; the local consistency gate rejects that ordering within one checkout. No separate released boolean is maintained. Before declaring a greater version unreleased, verify that no published release has advanced the record. An alpha, beta, or release-candidate product publication establishes released Session-format obligations. GitHub’s prerelease flag does not make persisted user data disposable. A missing release record is not evidence of non-publication. The [versioning and authority decision](../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md) owns compatibility decisions; [released-format migration](../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md) owns immutable generations and adjacent conversion. The [format references](persistence-changes/historical-formats/README.md) document every integer from zero through the checkout writer, with historical schemas and the existing current catalog. + +## Finalization record + +```yaml session-format-finalization +latestFinalizedVersion: 4 +``` + +V4 has an accepted compatibility baseline in the [checkpoint](persistence-changes/finalized/v4.json). Backward-compatible schema changes may remain V4 through new acknowledgement records. Breaking changes require a higher writer version and their own header transition; they cannot reuse the accepted 3→4 transition. Accepted machine records and after schemas remain immutable. [Checkpoint rules](persistence-changes/README.md#compatibility-rules) define the comparison. + +Finalization does not freeze every future V4 addition and does not assert publication. The release record below retains the independently verified published version. Ordinary comments, aliases, source locations, and implementation fixes preserving the accepted meaning do not change this baseline. + +Before the first V4 publication, every integration of a newer V3-writing master must pass the [explicit V3 vocabulary check](cookbook/adding-a-session-format-version.md#final-v3-vocabulary) against the recorded local source commit. Verify the source pin’s freshness and review new event payload conversions before updating the migration-owned set. After publication, the final V3 vocabulary remains historical and independent of current V4 additions. + ## Release record @@ -41,7 +55,7 @@ When a structural writer change is implemented, update the code constant and adj The [documentation-standard test](../scripts/doc-standard.spec.ts) checks record structure, bilingual equality, evidence-tag and writer-path consistency, and that the documented release does not exceed the checkout writer. This keyless check does not query GitHub or prove that the record is up to date; publication verification remains part of the release update. -Use “current format” and “next adjacent version” for general behavior. Keep explicit numbers for fixed migration inputs and outputs, wire schemas, historical evidence, and tests of those particular versions. The [format-version cookbook](cookbook/adding-a-session-format-version.md) uses N for the verified latest released format and N+1 for its successor. +Use “current format” and “next adjacent version” for general behavior. Keep explicit numbers for fixed migration inputs and outputs, wire schemas, historical evidence, and tests of those particular versions. The [format-version cookbook](cookbook/adding-a-session-format-version.md) uses N for the latest finalized or released format and N+1 for its successor. ## Dev Note diff --git a/docs/session-format-status.zh.md b/docs/session-format-status.zh.md index a54e98b32b..31e1710632 100644 --- a/docs/session-format-status.zh.md +++ b/docs/session-format-status.zh.md @@ -4,11 +4,12 @@ ## 概述 -本参考区分工作区的 Session 写入器版本与最新已发布的 Session 格式。代码常量拥有写入器版本;下方发布记录拥有最新已发布格式及其发布证据。其他文档链接到这里,而不重复声明哪个版本是当前、下一个或尚未发布的版本。 +本参考区分工作区写入器、已接受兼容性基线与最新已发布的 Session 格式。代码常量拥有写入器版本;下方定稿记录和发布记录分别标识已接受历史与发布证据。其他文档链接到这里,不重复这些值。 ## 目录 - [单一真源](#sources-of-truth) +- [定稿记录](#finalization-record) - [发布记录](#release-record) - [更新记录](#updating-the-record) - [开发备注](#dev-note) @@ -18,12 +19,25 @@ - **工作区写入器:**[核心 Session 类型](../packages/core/session/src/types.ts)中的 `SESSION_FORMAT_VERSION` 是代码中唯一手工维护的当前写入器版本号。[目录生成器](../scripts/gen-session-format-catalog.ts)推导 codec 顺序,并检查相邻迁移是否到达该版本。包版本、codec 导出名称、fixture(测试前置数据)文件名或投影缓存版本都不是写入器版本的权威来源。 - **最新已发布格式:**下方记录中的 `latestReleasedVersion` 标识已发布的 Session 格式。`evidenceTag` 指定一个已发布的产品版本,其标签对应的写入器具有该值;它不必是首次携带该格式的发布。双语副本按同一记录校验,不作为独立决策维护。 -- **发布状态:**比较写入器常量与已核实的发布记录。相等表示写入器格式已经发布。写入器版本更高表示它是超出记录中发布版本的开发目标。用较新分支中已核实的记录对比旧工作区时,较低的写入器版本表示较旧的写入器格式;本地一致性门禁会拒绝同一工作区内的这种大小关系。不另行维护 released 布尔值。在声明更高版本尚未发布前,必须核实是否已有产品发布推进了记录。 +- **发布状态:**比较写入器常量与已核实的发布记录。相等表示写入器格式已经发布。写入器版本更高表示发布记录尚未收录它;独立的定稿记录标识已接受的兼容性基线。用较新分支中已核实的记录对比旧工作区时,较低的写入器版本表示较旧的写入器格式;本地一致性门禁会拒绝同一工作区内的这种大小关系。不另行维护 released 布尔值。在声明更高版本尚未发布前,必须核实是否已有产品发布推进了记录。 产品的 alpha、beta 或 release-candidate 发布都会确立已发布 Session 格式的义务。GitHub 的 prerelease 标记不会让持久化用户数据成为可丢弃数据。缺少发布记录不代表尚未发布。[版本与真源决策](../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md)拥有兼容性决策;[已发布格式迁移](../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md)拥有不可变代际与相邻转换规则。 [格式参考](persistence-changes/historical-formats/README.zh.md)记录从零到工作区写入器的每个整数版本,提供历史 schema 并引用现有的当前目录。 + +## 定稿记录 + +```yaml session-format-finalization +latestFinalizedVersion: 4 +``` + +V4 的已接受兼容性基线保存在[检查点](persistence-changes/finalized/v4.json)中。向后兼容的 schema 变更可以通过新的确认记录保留 V4。破坏性变更要求更高的写入器版本及自身的头版本转换,不能复用已接受的 3→4 转换。已接受的机器记录与变更后 schema 保持不可变。[检查点规则](persistence-changes/README.zh.md#compatibility-rules)规定比较方法。 + +定稿不冻结 V4 之后的每项新增,也不表示已发布。下方发布记录保留独立验证的已发布版本。普通注释、别名、源码位置,以及保留已接受含义的实现修复,不改变该基线。 + +首次发布 V4 前,每次集成仍写入 V3 的较新 master 都必须对已记录的本地源提交执行[显式 V3 词汇校验](cookbook/adding-a-session-format-version.zh.md#final-v3-vocabulary)。更新迁移所有的集合前,要核验源 pin 的新鲜度并审查新事件 payload 的转换。发布后,最终 V3 词汇保持为历史定义,与当前 V4 新增事件无关。 + ## 发布记录 @@ -41,7 +55,7 @@ evidenceTag: dsh-v0.1.5-alpha.1 [文档标准测试](../scripts/doc-standard.spec.ts)检查记录结构、双语一致性、证据标签及写入器路径一致性,以及文档中的已发布版本不高于工作区写入器。这个无密钥检查不会查询 GitHub,也不能证明记录是最新的;核实发布事实仍属于发布更新的一部分。 -一般行为使用“当前格式”和“下一条相邻版本”等表述。固定迁移的输入与输出、协议 schema、历史证据及针对特定版本的测试保留明确版本号。[格式版本实操手册](cookbook/adding-a-session-format-version.zh.md)用 N 表示已核实的最新发布格式,用 N+1 表示其后继版本。 +一般行为使用“当前格式”和“下一条相邻版本”等表述。固定迁移的输入与输出、协议 schema、历史证据及针对特定版本的测试保留明确版本号。[格式版本实操手册](cookbook/adding-a-session-format-version.zh.md)用 N 表示最新已定稿或已发布格式,用 N+1 表示其后继版本。 ## 开发备注 diff --git a/docs/subsystems/llm-streaming.i18n.yaml b/docs/subsystems/llm-streaming.i18n.yaml index 9741b0084c..757474dd41 100644 --- a/docs/subsystems/llm-streaming.i18n.yaml +++ b/docs/subsystems/llm-streaming.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/llm-streaming.md -llm-streaming.md: 30dd26042b4894b294a67918006d9b607eadc6b2 -llm-streaming.zh.md: 6e5f1ff268e0c22a37c64a8f954c134bf71b3b73 +llm-streaming.md: 07fc6599bc5d4eb5a4af9b566032004932052585 +llm-streaming.zh.md: 079a33599d1e5169af6402db2b2abdd7dc978369 diff --git a/docs/subsystems/llm-streaming.md b/docs/subsystems/llm-streaming.md index 30dd26042b..07fc6599bc 100644 --- a/docs/subsystems/llm-streaming.md +++ b/docs/subsystems/llm-streaming.md @@ -2,7 +2,7 @@ English | [中文](llm-streaming.zh.md) -The conversation and streaming types from [`packages/llm`](../../packages/llm/README.md): the `Message`/`ContentBlock` variants every request and durable history share, the fully assembled model request, the raw `StreamChunk` protocol, the adapter contract every adapter must implement, and the shared assembler. The [core packages](core.md) hold and log these values on every turn; this page declares them. +The conversation and streaming types from [`packages/llm`](../../packages/llm/README.md): durable `Message` values, request-only user inputs, shared `ContentBlock` variants, the fully assembled model request, the raw `StreamChunk` protocol, the adapter contract every adapter must implement, and the shared assembler. The [core packages](core.md) hold and log these values on every turn; this page declares them. Source: [`packages/llm/llm/src/types.ts`](../../packages/llm/llm/src/types.ts) @@ -17,7 +17,9 @@ Source: [`packages/llm/llm/src/types.ts`](../../packages/llm/llm/src/types.ts) ```ts type-equiv /** * Merge-extensible content blocks keyed by `type`. New core blocks must land - * with adapter, UI, and compaction support. + * with adapter, UI, and compaction support. Developer tool-change blocks are + * reserved for Session V4 persistence; providers and UI reject them until + * their producers and consumers are implemented together. */ interface ContentBlockMap { 'text': TextBlock @@ -25,11 +27,12 @@ interface ContentBlockMap { 'image': ImageBlock 'file': FileBlock 'tool-call': ToolCallBlock - 'tool-result': ToolResultBlock + 'tool-addition': ToolAdditionBlock + 'tool-removal': ToolRemovalBlock } ``` -The block interfaces (full fields in source): `TextBlock` (`text`), `ReasoningBlock` (thinking, distinct from visible text), `ImageBlock` (a durable [image attachment](attachment.md)), `FileBlock` (a durable verbatim [file attachment](attachment.md) that request assembly projects to handle text for every route), `ToolCallBlock` (`id: ToolCallId`, `name`, raw-JSON `arguments`), and `ToolResultBlock` (`toolCallId`, nested `content: ContentBlock[]`, `isError?`). `ContentBlock = ContentBlockMap[ContentBlockType]`. A new modality belongs in the merge-extensible map only when its adapter, UI, compaction, and durable replay paths honor it. +The block interfaces (full fields in source): `TextBlock` (`text`), `ReasoningBlock` (thinking, distinct from visible text), `ImageBlock` (a durable [image attachment](attachment.md)), `FileBlock` (a durable verbatim [file attachment](attachment.md) that request assembly projects to handle text for every route), and `ToolCallBlock` (`id: ToolCallId`, `name`, raw-JSON `arguments`). Tool results are first-class `ToolResultMessage` values with `toolCallId`, result `content`, and optional `isError`; they are not content blocks. `ContentBlock = ContentBlockMap[ContentBlockType]`. A new modality belongs in the merge-extensible map only when its adapter, UI, compaction, and durable replay paths honor it. Developer tool-change blocks are a persistence-only exception described in the [decision](../../.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md). Image access belongs to request serialization rather than the durable attachment or deterministic request-image version. `resolveImageAttachmentAccess()` combines the attachment provider's optional host object path with a mapping supplied by the consumer for the current tool execution filesystem. The result is available only for that request and does not participate in `variantId`. @@ -64,31 +67,27 @@ interface AssistantProviderMetadata { ``` ```ts type-equiv -/** One immutable message representation shared by delivery, durable history, and model requests. */ -interface Message { - /** Stable identity preserved across every representation boundary. */ - readonly id: MessageId - /** Provider-neutral conversation role. */ - readonly role: 'system' | 'user' | 'assistant' - /** Exact model-facing blocks. */ - readonly content: ContentBlock[] - /** Required source fields supplied by the producer. */ - readonly source: MessageSource -} +/** Any persisted conversation message, discriminated by its `role`. */ +type Message = MessageRoleMap[keyof MessageRoleMap] ``` +`DeveloperMessage` records incremental agent session changes in conversation order with the `developer` role. `ToolAdditionBlock.toolName` activates the definition selected by the containing Session event's historical header reference; `ToolRemovalBlock.toolName` removes the active definition. Both blocks are rejected in other message roles. `deferLoading` independently requests deferred definition loading without requiring an addition record. See [Session](../../packages/core/session/README.md) for header binding and the [LLM package](../../packages/llm/llm/README.md#known-limitations-and-deferred-work) for provider support limits. + Where a message came from is itself a merge-extensible sum type: ```ts type-equiv /** - * Where a message (or injected content) came from. - * Merge-extensible sum type — plugins add their own `kind`s. + * Where a message (or injected content) came from, in the harness's own + * vocabulary. Merge-extensible sum type — each producer declares its own + * `kind` in its own module; there is no shared catch-all `plugin` kind. + * Model and tool sources answer their role messages; user messages carry any + * producer's kind, and consumers fall through unknown kinds. */ interface MessageSourceMap { user: { kind: 'user' } - plugin: { kind: 'plugin'; plugin: string } & ContextFormed model: ModelMessageSource tool: ToolMessageSource + 'system-prompt': SystemPromptMessageSource } ``` @@ -415,10 +414,10 @@ declare class BlockAssembler { get replayState(): ReplayEnvelope | undefined; /** * The assembled assistant message. - * @param source - producer attribution for the assembled message. + * @param source - provider/model attribution (without the `kind` tag) for the assembled message. * @returns a frozen assistant-role message over `blocks()` (same open-block assembly rules). */ - message(source: MessageSource = { kind: 'plugin', plugin: 'dsh-llm/assembler' }): Message; + message(source: Omit): AssistantMessage; } ``` @@ -577,6 +576,23 @@ interface LlmResolvedModelInfo extends LlmModelInfo { } ``` +Auxiliary callers can provide user content without a durable identity or source. Existing `Message[]` histories remain valid request inputs. Session writes, Agent delivery, and recorded title requests continue to require durable messages. + +```ts type-equiv +/** User input for one LLM request; it has no durable Session identity or source. */ +interface RequestUserInput { + readonly role: 'user' + readonly content: UserMessage['content'] + readonly id?: never + readonly source?: never +} +``` + +```ts type-equiv +/** A durable conversation message or a user input used only for one request. */ +type RequestMessage = Message | RequestUserInput +``` + ```ts type-equiv /** A single model request, fully assembled. */ interface GenerateOptions { @@ -589,9 +605,9 @@ interface GenerateOptions { * Ordered conversation messages, exactly as the provider sees them. A * loop-built request passes the derived history (dsh-agent-loop), whose * leading system-role message carries the system prompt; a hand-built - * one-shot passes any list. + * one-shot may include identity-free user inputs. */ - messages: Message[] + messages: RequestMessage[] /** * System prompt text for one-shot callers; adapters map it to the provider's * system slot ahead of `messages`. Loop-built requests leave it undefined. @@ -651,6 +667,12 @@ interface FinishReasonMap { * it from this package. */ interface ToolSchema { + /** + * Requests deferred loading of the tool definition into model context, + * independently of whether a tool-addition block records the tool. + * Uses Anthropic's defer_loading terminology. + */ + deferLoading?: true name: string description: string /** JSON Schema object for the arguments. */ @@ -1089,8 +1111,8 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen * (mutation throws): its content is a pure function of the session log (the * reconstructability Agent Note), so listeners read it, never rewrite it. - * Hand-built calls do not carry that marker; their messages already obey - * the immutable creation contract. + * Hand-built calls do not carry that marker; callers own their request + * inputs and must keep them unchanged until the stream settles. * @mode waterfall */ 'llm/stream'(this: LlmRuntime, options: GenerateOptions, next: () => AsyncIterable): AsyncIterable diff --git a/docs/subsystems/llm-streaming.zh.md b/docs/subsystems/llm-streaming.zh.md index 6e5f1ff268..079a33599d 100644 --- a/docs/subsystems/llm-streaming.zh.md +++ b/docs/subsystems/llm-streaming.zh.md @@ -2,7 +2,7 @@ [English](llm-streaming.md) | 中文 -[`packages/llm`](../../packages/llm/README.zh.md) 提供对话与流式输出类型:每个请求和持久历史共用的 `Message`/`ContentBlock` 变体、完整组装的模型请求、原始 `StreamChunk` 协议、每个适配器必须实现的适配器约定(adapter contract),以及共享的 assembler。[核心包](core.zh.md)在每个轮次持有并记录这些值;本页声明它们。 +[`packages/llm`](../../packages/llm/README.zh.md) 提供对话与流式输出类型:持久 `Message` 值、仅供请求使用的 user 输入、共用的 `ContentBlock` 变体、完整组装的模型请求、原始 `StreamChunk` 协议、每个适配器必须实现的适配器约定(adapter contract),以及共享的 assembler。[核心包](core.zh.md)在每个轮次持有并记录这些值;本页声明它们。 源码:[`packages/llm/llm/src/types.ts`](../../packages/llm/llm/src/types.ts) @@ -17,7 +17,9 @@ ```ts type-equiv /** * Merge-extensible content blocks keyed by `type`. New core blocks must land - * with adapter, UI, and compaction support. + * with adapter, UI, and compaction support. Developer tool-change blocks are + * reserved for Session V4 persistence; providers and UI reject them until + * their producers and consumers are implemented together. */ interface ContentBlockMap { 'text': TextBlock @@ -25,11 +27,12 @@ interface ContentBlockMap { 'image': ImageBlock 'file': FileBlock 'tool-call': ToolCallBlock - 'tool-result': ToolResultBlock + 'tool-addition': ToolAdditionBlock + 'tool-removal': ToolRemovalBlock } ``` -各块接口(完整字段见源码):`TextBlock`(`text`)、`ReasoningBlock`(thinking,区别于可见文本)、`ImageBlock`(一个持久的[图片附件](attachment.zh.md))、`FileBlock`(一个持久的原样[文件附件](attachment.zh.md),请求组装对每条路由都把它投影为 handle 文本)、`ToolCallBlock`(`id: ToolCallId`、`name`、原始 JSON `arguments`),以及 `ToolResultBlock`(`toolCallId`、嵌套 `content: ContentBlock[]`、`isError?`)。`ContentBlock = ContentBlockMap[ContentBlockType]`。仅当适配器、UI、压缩(compaction)和持久回放路径均支持某种新模态时,才将其纳入可合并扩展的 map。 +各块接口(完整字段见源码):`TextBlock`(`text`)、`ReasoningBlock`(thinking,区别于可见文本)、`ImageBlock`(一个持久的[图片附件](attachment.zh.md))、`FileBlock`(一个持久的原样[文件附件](attachment.zh.md),请求组装对每条路由都把它投影为 handle 文本)和 `ToolCallBlock`(`id: ToolCallId`、`name`、原始 JSON `arguments`)。工具结果是一等 `ToolResultMessage`,含有 `toolCallId`、结果 `content` 与可选的 `isError`;它不是内容块。`ContentBlock = ContentBlockMap[ContentBlockType]`。仅当适配器、UI、压缩(compaction)和持久回放路径均支持某种新模态时,才将其纳入可合并扩展的 map。 Developer 工具变更块属于仅持久化的例外,见[决策](../../.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md)。 图片访问方式属于请求序列化,不属于持久附件或确定性请求图片版本。`resolveImageAttachmentAccess()` 把附件提供方可选的宿主对象路径,与消费方为当前工具执行文件系统提供的映射组合起来。结果只适用于本次请求,不参与 `variantId`。 @@ -64,31 +67,27 @@ interface AssistantProviderMetadata { ``` ```ts type-equiv -/** One immutable message representation shared by delivery, durable history, and model requests. */ -interface Message { - /** Stable identity preserved across every representation boundary. */ - readonly id: MessageId - /** Provider-neutral conversation role. */ - readonly role: 'system' | 'user' | 'assistant' - /** Exact model-facing blocks. */ - readonly content: ContentBlock[] - /** Required source fields supplied by the producer. */ - readonly source: MessageSource -} +/** Any persisted conversation message, discriminated by its `role`. */ +type Message = MessageRoleMap[keyof MessageRoleMap] ``` +`DeveloperMessage` 以 `developer` 角色按对话顺序记录增量智能体 Session 变更。`ToolAdditionBlock.toolName` 激活由所在 Session 事件的历史请求头引用所选定的定义;`ToolRemovalBlock.toolName` 移除当前生效的定义。其他消息角色拒绝这两种内容块。`deferLoading` 独立控制工具定义的加载请求,不要求存在添加记录。请求头绑定见 [Session](../../packages/core/session/README.zh.md),提供方支持限制见 [LLM 包](../../packages/llm/llm/README.zh.md#known-limitations-and-deferred-work)。 + 消息来源本身也是一个可合并扩展的和类型: ```ts type-equiv /** - * Where a message (or injected content) came from. - * Merge-extensible sum type — plugins add their own `kind`s. + * Where a message (or injected content) came from, in the harness's own + * vocabulary. Merge-extensible sum type — each producer declares its own + * `kind` in its own module; there is no shared catch-all `plugin` kind. + * Model and tool sources answer their role messages; user messages carry any + * producer's kind, and consumers fall through unknown kinds. */ interface MessageSourceMap { user: { kind: 'user' } - plugin: { kind: 'plugin'; plugin: string } & ContextFormed model: ModelMessageSource tool: ToolMessageSource + 'system-prompt': SystemPromptMessageSource } ``` @@ -421,10 +420,10 @@ declare class BlockAssembler { get replayState(): ReplayEnvelope | undefined; /** * The assembled assistant message. - * @param source - producer attribution for the assembled message. + * @param source - provider/model attribution (without the `kind` tag) for the assembled message. * @returns a frozen assistant-role message over `blocks()` (same open-block assembly rules). */ - message(source: MessageSource = { kind: 'plugin', plugin: 'dsh-llm/assembler' }): Message; + message(source: Omit): AssistantMessage; } ``` @@ -583,6 +582,23 @@ interface LlmResolvedModelInfo extends LlmModelInfo { } ``` +辅助调用方可以提供不含持久身份或来源的 user 内容。既有 `Message[]` 历史仍然是有效的请求输入。Session 写入、Agent 投递和已记录的标题请求仍然要求持久消息。 + +```ts type-equiv +/** User input for one LLM request; it has no durable Session identity or source. */ +interface RequestUserInput { + readonly role: 'user' + readonly content: UserMessage['content'] + readonly id?: never + readonly source?: never +} +``` + +```ts type-equiv +/** A durable conversation message or a user input used only for one request. */ +type RequestMessage = Message | RequestUserInput +``` + ```ts type-equiv /** A single model request, fully assembled. */ interface GenerateOptions { @@ -595,9 +611,9 @@ interface GenerateOptions { * Ordered conversation messages, exactly as the provider sees them. A * loop-built request passes the derived history (dsh-agent-loop), whose * leading system-role message carries the system prompt; a hand-built - * one-shot passes any list. + * one-shot may include identity-free user inputs. */ - messages: Message[] + messages: RequestMessage[] /** * System prompt text for one-shot callers; adapters map it to the provider's * system slot ahead of `messages`. Loop-built requests leave it undefined. @@ -657,6 +673,12 @@ interface FinishReasonMap { * it from this package. */ interface ToolSchema { + /** + * Requests deferred loading of the tool definition into model context, + * independently of whether a tool-addition block records the tool. + * Uses Anthropic's defer_loading terminology. + */ + deferLoading?: true name: string description: string /** JSON Schema object for the arguments. */ @@ -1095,8 +1117,8 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen * (mutation throws): its content is a pure function of the session log (the * reconstructability Agent Note), so listeners read it, never rewrite it. - * Hand-built calls do not carry that marker; their messages already obey - * the immutable creation contract. + * Hand-built calls do not carry that marker; callers own their request + * inputs and must keep them unchanged until the stream settles. * @mode waterfall */ 'llm/stream'(this: LlmRuntime, options: GenerateOptions, next: () => AsyncIterable): AsyncIterable diff --git a/docs/subsystems/persistence.i18n.yaml b/docs/subsystems/persistence.i18n.yaml index 1abbf9957d..bddbecf1f1 100644 --- a/docs/subsystems/persistence.i18n.yaml +++ b/docs/subsystems/persistence.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/persistence.md -persistence.md: 7e18e9bbfec8c7aa81525da33ad3cffa4681ea73 -persistence.zh.md: 8250fb93b20dc33c2df705fd2c7092bc8dea155c +persistence.md: 53a001f438793740a55acd5abf45536164e63031 +persistence.zh.md: 9f3c18a82885df51f62cb2d9cda901d483ffd65e diff --git a/docs/subsystems/persistence.md b/docs/subsystems/persistence.md index 7e18e9bbfe..53a001f438 100644 --- a/docs/subsystems/persistence.md +++ b/docs/subsystems/persistence.md @@ -203,8 +203,8 @@ interface CreateSessionOptions { readonly seed?: readonly SessionEvent[] /** * Exact fork-inherited prefix length when `meta.isSeeded` is true. The - * constructor seed is exactly this inherited prefix; the constructor - * appends the child-owned tagged marker at the cut. + * constructor appends the child-owned tagged marker at the cut unless + * the seed already includes it followed by child-owned fork closers. */ readonly inheritedEventCount?: SessionLogOffset /** diff --git a/docs/subsystems/persistence.zh.md b/docs/subsystems/persistence.zh.md index 8250fb93b2..9f3c18a828 100644 --- a/docs/subsystems/persistence.zh.md +++ b/docs/subsystems/persistence.zh.md @@ -203,8 +203,8 @@ interface CreateSessionOptions { readonly seed?: readonly SessionEvent[] /** * Exact fork-inherited prefix length when `meta.isSeeded` is true. The - * constructor seed is exactly this inherited prefix; the constructor - * appends the child-owned tagged marker at the cut. + * constructor appends the child-owned tagged marker at the cut unless + * the seed already includes it followed by child-owned fork closers. */ readonly inheritedEventCount?: SessionLogOffset /** diff --git a/docs/subsystems/session-telemetry.i18n.yaml b/docs/subsystems/session-telemetry.i18n.yaml index 52ebdadf24..c8b935f67b 100644 --- a/docs/subsystems/session-telemetry.i18n.yaml +++ b/docs/subsystems/session-telemetry.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/session-telemetry.md -session-telemetry.md: f452dc6fa9064689664bcaed08205d30def822e6 -session-telemetry.zh.md: 59c817cca945e3f972e30104104f44fb15006aa5 +session-telemetry.md: 18fe935e5e02b7fb26bb9120b031a4685ca603aa +session-telemetry.zh.md: 1b3807d2e38bea141953faba990a6fee460b40b9 diff --git a/docs/subsystems/session-telemetry.md b/docs/subsystems/session-telemetry.md index f452dc6fa9..18fe935e5e 100644 --- a/docs/subsystems/session-telemetry.md +++ b/docs/subsystems/session-telemetry.md @@ -12,7 +12,7 @@ Source: [`packages/session/session-telemetry/src/index.ts`](../../packages/sessi /** * Severity of a telemetry record, pre-mapped at capture so a receiver can * alert with zero configuration: `error` for events whose own outcome flag - * says so (the tool-result block's `isError`, `turn/end` error reasons) and for + * says so (the tool message's `isError`, `turn/end` error reasons) and for * `agent-error` operational records. Captured events otherwise default to * `info`; `warn` remains available to `session-telemetry/record` policies and * backends. @@ -55,7 +55,7 @@ interface SessionTelemetryRecord { } ``` -Every canonical [session event](session.md), including each `assistant/message` or `assistant/attempt` with its complete compact stream and every plugin-merged type the seam never heard of, passes through whole as one ordered ledger record. Process-local `agent/assistant-stream` frames do not enter this durable feed. A new Session object starts at its lifecycle boundary unless the backend selects `includeHistory`; re-adopting the same object resumes after its handoff cursor. Delivery is best-effort: the cursor marks handed-off, not delivered, and records can be lost (crash, reload window) or duplicated (new-object replay, SDK retries), so receivers dedupe ledger records on `(session.id, session.format_version, event.seq)`; ops records deliberately omit that identity — they are signals to alert on, not entries to sum, and tolerate duplicates instead. +Every canonical [session event](session.md), including each `assistant/message` or `assistant/attempt` with its complete compact stream and every plugin-merged type the seam never heard of, passes through whole as one ordered ledger record. Process-local `agent/assistant-stream` frames do not enter this durable feed. A new fork starts at its child-owned suffix, including the inherited marker and fork closers; restored Sessions start after their stored prefix, including restored forks. The backend can select `includeHistory` to include the complete prefix; re-adopting the same object resumes after its handoff cursor. Delivery is best-effort: the cursor marks handed-off, not delivered, and records can be lost (crash, reload window) or duplicated (new-object replay, SDK retries), so receivers dedupe ledger records on `(session.id, session.format_version, event.seq)`; ops records deliberately omit that identity — they are signals to alert on, not entries to sum, and tolerate duplicates instead. ## The sharing disclosure @@ -80,7 +80,7 @@ type SessionTelemetryCapture = 'live' | 'on-demand' interface SessionTelemetryCaptureOptions { /** Follow live events, or wait for explicit capture; defaults to live. */ capture?: SessionTelemetryCapture - /** Include stored history before this lifecycle; defaults to false. */ + /** Include inherited fork history and stored history from earlier lifecycles; defaults to false. */ includeHistory?: boolean } ``` diff --git a/docs/subsystems/session-telemetry.zh.md b/docs/subsystems/session-telemetry.zh.md index 59c817cca9..1b3807d2e3 100644 --- a/docs/subsystems/session-telemetry.zh.md +++ b/docs/subsystems/session-telemetry.zh.md @@ -12,7 +12,7 @@ /** * Severity of a telemetry record, pre-mapped at capture so a receiver can * alert with zero configuration: `error` for events whose own outcome flag - * says so (the tool-result block's `isError`, `turn/end` error reasons) and for + * says so (the tool message's `isError`, `turn/end` error reasons) and for * `agent-error` operational records. Captured events otherwise default to * `info`; `warn` remains available to `session-telemetry/record` policies and * backends. @@ -55,7 +55,7 @@ interface SessionTelemetryRecord { } ``` -每条权威[会话事件](session.zh.md)都会完整透传为一条有序 ledger 记录,包括每个携带完整紧凑 stream 的 `assistant/message` 或 `assistant/attempt`,以及该 seam 从未听说过、由插件合并进来的类型。进程本地 `agent/assistant-stream` frame 不进入该持久 feed。新 Session 对象从其生命周期边界开始,除非后端选择 `includeHistory`;重新收养同一对象时会从 handoff 游标之后继续。投递是尽力而为的:游标标记的是「已交接」而非「已送达」,记录可能丢失(崩溃、重载窗口)也可能重复(新对象回放、SDK 重试),因此接收端对 ledger 记录基于 `(session.id, session.format_version, event.seq)` 去重;ops 记录刻意省略这类标识——它们是用于告警的信号,而非用于累加的条目,重复被容忍而非被去重。 +每条权威[会话事件](session.zh.md)都会完整透传为一条有序 ledger 记录,包括每个携带完整紧凑 stream 的 `assistant/message` 或 `assistant/attempt`,以及该 seam 从未听说过、由插件合并进来的类型。进程本地 `agent/assistant-stream` frame 不进入该持久 feed。新 fork 从子会话自有后缀开始,包括继承标记和 fork 结束事件;恢复的 Session 从已存储前缀之后开始,包括恢复的 fork。后端可以选择 `includeHistory` 来包含完整前缀;重新收养同一对象时会从 handoff 游标之后继续。投递是尽力而为的:游标标记的是「已交接」而非「已送达」,记录可能丢失(崩溃、重载窗口)也可能重复(新对象回放、SDK 重试),因此接收端对 ledger 记录基于 `(session.id, session.format_version, event.seq)` 去重;ops 记录刻意省略这类标识——它们是用于告警的信号,而非用于累加的条目,重复被容忍而非被去重。 ## 共享披露 @@ -80,7 +80,7 @@ type SessionTelemetryCapture = 'live' | 'on-demand' interface SessionTelemetryCaptureOptions { /** Follow live events, or wait for explicit capture; defaults to live. */ capture?: SessionTelemetryCapture - /** Include stored history before this lifecycle; defaults to false. */ + /** Include inherited fork history and stored history from earlier lifecycles; defaults to false. */ includeHistory?: boolean } ``` diff --git a/docs/subsystems/session.i18n.yaml b/docs/subsystems/session.i18n.yaml index 4efb2c553b..83eecfd1c7 100644 --- a/docs/subsystems/session.i18n.yaml +++ b/docs/subsystems/session.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/session.md -session.md: 69f0ee565e47191e2468a857d12eb7d255c9ecdb -session.zh.md: 56a0502fcbccf89625833d116cb2eb2a1fcb49f7 +session.md: 62f7785d4d1db9c30706a8b967e6f4073b810149 +session.zh.md: 7cd3c38162df209d245d3f1085ab1edce002531a diff --git a/docs/subsystems/session.md b/docs/subsystems/session.md index 69f0ee565e..62f7785d4d 100644 --- a/docs/subsystems/session.md +++ b/docs/subsystems/session.md @@ -11,8 +11,8 @@ Source: [`packages/core/session/src/types.ts`](../../packages/core/session/src/t The append-only event types. Merge-extensible: a plugin declares extra event types via declaration merging — e.g. the [compaction seam](compaction.md) adds `compaction/start` / `compaction/summary` / `compaction/end`, and `@deepseek-ai/dsh-hook-protocol` adds log-only `hook/invoked` / `hook/result` records for a hook bridge. Like `compaction/*`, these are NOT `SurfaceEventType`s (no `surfaceOp`). The generated [persistence log event catalog](../persistence-catalog.md) enumerates every member — core and merged — with its payload, surface badge, and declaration site. ```ts type-equiv -/** A user-role specialization of the one shared message representation. */ -interface UserMessage extends Message { +/** A user-role specialization of the shared message representation. */ +interface UserMessage extends MessageBase { readonly role: 'user' } ``` @@ -53,6 +53,14 @@ interface SessionEventMap { * project their `content` verbatim; `source` tells them apart. */ 'user/message': UserMessage + /** An incremental agent session change admitted at the named turn and step. */ + 'developer/message': { + turn: number + step: number + message: DeveloperMessage + /** Earlier request/header defining every tool addition; required exactly when additions are present. */ + headerSeq?: SessionSeq + } /** * The rendered system prompt on the model-visible surface. The loop appends * the first one as surface node 0 before the step's first `user/message`. @@ -116,7 +124,7 @@ interface SessionEventMap { message: ToolResultMessage /** * Optional failure identity and raw user-facing reason, outside model content; - * allowed only when the tool-result block has `isError: true`. + * allowed only when the message has `isError: true`. */ error?: { name: string; code: string; reason?: string } meta?: JsonValue @@ -139,19 +147,21 @@ interface SessionEventMap { */ 'request/context': RequestContext /** - * Marks the end of a constructor seed. Events before it have smaller seq - * values and came from the seed (resume, fork, or replay); this lifecycle - * produced none of them. This log-only event is the durable projection of - * {@link Session.firstLiveSeq}. + * Separates inherited or restored history from later lifecycle-owned work. + * This log-only marker need not be at {@link Session.firstLiveSeq}: a fork + * seed can already contain its tagged marker and child-owned synthetic + * closers before construction. * * A fresh fork child owns one `{ inherited: true }` marker at its exact * inherited-prefix cut, even when that prefix ends in an ancestor marker. - * The last tagged marker is the current Session's cut; untagged markers keep - * ordinary restore and replay lifecycle boundaries. + * `buildForkSeed` appends that marker before any synthetic closers; the + * `Session` constructor supplies it when given only the inherited prefix. + * The last tagged marker is the current Session's cut; untagged markers + * keep ordinary restore and replay lifecycle boundaries. * - * `Session`'s constructor is the only legitimate writer. The invariant - * companion deliberately constrains nothing here, so a plugin appending one - * would silently classify every live bracket before it as seed history. + * Only the `Session` constructor and `buildForkSeed` may create this marker. + * The invariant companion deliberately constrains nothing here, so a plugin + * appending one would silently classify every live bracket before it as seed history. * * An owner of a standalone open/close bracket (`compaction/start` … * `compaction/end`) reads it because seed history and live work are otherwise @@ -186,6 +196,10 @@ interface EpochHeader { adapterDefaults?: LlmCallConfigAdapterDefaults /** Assembled tool schemas; absent for a tool-less request. */ tools?: ToolSchema[] + /** Retired request text; system prompts belong to system/message events. + * @persistenceReserved + */ + system?: never } ``` @@ -277,11 +291,11 @@ type SessionEvent = { `SessionEventType = keyof SessionEventMap`. Because `SessionEventMap` is merge-extensible, switches over `SessionEvent` must NOT use `assertNever` — a plugin-added variant is a valid unknown value; handle the known cases and fall through `default`. -Every surface event requires `surfaceOp`; known log-only events forbid both surface metadata fields. Native unknown or obsolete ignorable envelopes remain opaque. `assistant/message` embeds its provider stream and forbids `sourceEventSeqs`. System, user, and tool surface events may cite a complete non-empty set of unique earlier events when source attribution or replacement coverage requires it. A `tool/result` may carry `data.error` only when its tool-result block has `isError: true`; failure identity remains optional for failed results. +Every surface event requires `surfaceOp`; known log-only events forbid both surface metadata fields. Native unknown or obsolete ignorable envelopes remain opaque. `assistant/message` embeds its provider stream and forbids `sourceEventSeqs`. System, user, and tool surface events may cite a complete non-empty set of unique earlier events when source attribution or replacement coverage requires it. A `tool/result` may carry `data.error` only when its message has `isError: true`; failure identity remains optional for failed results. ## Surface types -The four message-producing types (`SurfaceEventType` — `system/message`, `user/message`, `assistant/message`, `tool/result`) carry surface metadata declaring how they join the ordered derived surface. `system/message` holds the rendered system prompt: the loop appends the first one as surface node 0 and, when the prompt changes, replaces exactly the latest system node or appends a new one on an in-history route; the surface fold rejects any other replacement covering a `system/message` at node 0, while a later system node is ordinary history that a compaction replacement may shadow. See the [session surface Agent Note](../../.agents/notes/implemented/architecture/2026-06-18-session-surface.md). +The message-producing types (`SurfaceEventType` — `system/message`, `developer/message`, `user/message`, `assistant/message`, `tool/result`) carry surface metadata declaring how they join the ordered derived surface. `system/message` holds the rendered system prompt: the loop appends the first one as surface node 0 and, when the prompt changes, replaces exactly the latest system node or appends a new one on an in-history route; the surface fold rejects any other replacement covering a `system/message` at node 0, while a later system node is ordinary history that a compaction replacement may shadow. See the [session surface Agent Note](../../.agents/notes/implemented/architecture/2026-06-18-session-surface.md). ### `SurfaceEventType` — the message-producing subset of event types @@ -294,6 +308,7 @@ The four message-producing types (`SurfaceEventType` — `system/message`, `user */ type SurfaceEventType = | 'system/message' + | 'developer/message' | 'user/message' | 'assistant/message' | 'tool/result' @@ -458,29 +473,26 @@ declare class Session { /** The session identity, derived from its durable header's single copy. */ get id(): SessionId; /** - * The first seq appended IN THIS PROCESS: the length of the constructor - * seed (0 without one). Events with smaller seq values entered through - * construction — replay, fork, or resume — and were never published on the - * `session/event` firehose (constructor seeds do not emit). This offset marks - * the constructor-input boundary for lifecycle ownership and persistence - * adoption; consumers that need complete canonical history still start at - * seq 0. Distinct from {@link inheritedEventCount}, the DURABLE - * fork-lineage cut: a resumed session's constructor seed is its full stored - * log, while the inherited count keeps the original fork value — this field is the - * in-process construction fact. + * The constructor seed length (0 without one), before any marker appended + * during construction. Seed events never publish on `session/event`. A + * marker appended before the store attaches occupies this seq without + * publishing either; otherwise this seq is available for the next append. * - * Not persisted itself: a seeded session projects it into the log as the - * `session/end-seed` event, which is what a consumer reading STORED history - * reads. Locate the LAST such event, not necessarily one at this seq — a - * seed already ending in one is not re-marked, so reopening an untouched - * session leaves that event at a smaller seq than `firstLiveSeq`. Prefer - * this field in-process: it is exact before the marker reaches storage. - * - * When this lifecycle appends the marker, it occupies this seq before the - * store attaches and therefore does not publish either. Otherwise this seq - * holds an ordinary published write. + * This in-process offset is not persisted. A fork seed can already contain + * the child's inherited marker and synthetic closers, so its child-owned + * history starts at {@link inheritedEventCount}, before this offset. A + * resumed Session's seed contains its full stored log, while its inherited + * count keeps the durable fork cut. Consumers needing complete canonical + * history start at seq 0. */ readonly firstLiveSeq: SessionLogOffset; + /** + * First event produced for this object lifecycle. A new fork includes its + * child-owned seed marker and closers; a restored Session starts after its + * complete stored prefix. This in-process capture offset is not persisted. + */ + readonly firstLifecycleSeq: SessionLogOffset; + /** * Create a detached session by validating and snapshotting borrowed seed * events and storage metadata. @@ -651,7 +663,7 @@ declare class Session { - `user/message` → a user message carrying exact `content`; an optional envelope remains log-only display metadata. - `assistant/message` → an assistant message with the provider and model that produced it plus optional adapter-private replay state. Its embedded compact stream is replay, usage, and UI evidence rather than a second message. An **empty-content** `assistant/message` is also skipped — a max-tokens step cut off with no content still records an `assistant/message` to hold its stream, usage, provider, and model, but a content-less assistant turn must not enter the provider transcript. -- `tool/result` → a user message carrying a `tool-result` block. +- `tool/result` → a first-class tool-role message carrying its result content and tool-call identity. - `user/message` (injected context, i.e. non-`user` source) → a user-role message carrying its `content` verbatim at its chronological position; its typed source names the producer and carries any producer-specific data. Everything else (`turn/*`, `step/*`, `assistant/attempt`, plugin-owned `llm/retry`) is structural and does not project into a message. Token accounting expands the embedded stream on each `assistant/message` or `assistant/attempt`, while the message's top-level `usage` remains the committed-message authority when present. A failed model-request attempt therefore retains its provider usage without fabricating an assistant message. Current logical validation rejects request headers and assistant messages that omit provider/model instead of guessing a route; supported historical representations are normalized and validated by their adjacent format edge before a current Session exists. @@ -698,10 +710,17 @@ interface TurnEndReasonMap { * the events recorded before the crash remain intact. */ interrupted: { kind: 'interrupted' } + /** + * Fork-seed construction closed a turn that was still open at the fork + * boundary in the source session. Only fork seeds carry this marker — the + * loop never emits it — and the source events before the boundary remain + * intact in the child. + */ + forked: { kind: 'forked' } } ``` -`max-tokens` mirrors the model-call `FinishReason` of the same name: any `max-tokens` step in a turn makes the whole turn end `max-tokens` rather than `completed` (the cut-short fact wins over a later continuation), so a consumer can tell a clean stop from a truncated one. Cancellation and errors remain distinct outcomes. `interrupted` is the one reason no loop emits—it is synthesized by crash recovery (see [persistence.md](persistence.md)). The map is merge-extensible. +`max-tokens` mirrors the model-call `FinishReason` of the same name: any `max-tokens` step in a turn makes the whole turn end `max-tokens` rather than `completed` (the cut-short fact wins over a later continuation), so a consumer can tell a clean stop from a truncated one. Cancellation and errors remain distinct outcomes. The loop emits neither `interrupted` nor `forked` live: crash recovery synthesizes `interrupted` (see [persistence.md](persistence.md)), while fork-seed construction synthesizes `forked`. The map is merge-extensible. ## Execution enclosure and standalone events @@ -711,7 +730,7 @@ The optional `dsh-session/invariant` companion enforces the relations owned by c ## The end-seed boundary: `session/end-seed` -A fresh fork constructor requires its seed to equal the inherited prefix and appends `session/end-seed { inherited: true }` at the exact durable cut. A restore retains that tagged marker and appends an ordinary `session/end-seed {}` only when its complete stored seed does not already end in a marker. Both forms are log-only and produce no message; `Session`'s constructor is the only legitimate writer. +`buildForkSeed` appends `session/end-seed { inherited: true }` at the exact inherited-prefix cut before adding synthetic fork closers. The `Session` constructor retains that prepared marker or appends one when given only the inherited prefix. A restore retains the tagged marker and appends an ordinary `session/end-seed {}` only when its complete stored seed does not already end in a marker. Both forms are log-only and produce no message; only the constructor and `buildForkSeed` may create them. For fork lineage, locate the LAST marker whose payload carries `inherited: true`; current-format decoding requires it exactly when `SessionHeader.isSeeded` is true and derives `inheritedEventCount` from its seq. For lifecycle ownership, locate the last `session/end-seed` of either form. Reopening a seed that already ends in any marker does not append another ordinary marker. @@ -834,8 +853,10 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' | @Remote('rename') rename(request: SessionRenameRequest): Promise /** - * Fork one cold-readable completed-turn prefix into a new Session. - * @param request - source Session and optional event anchor. + * Fork one cold-readable exact event prefix into a new Session. An omitted + * boundary selects the latest completed-turn prefix; an open cut receives + * synthetic fork closers. + * @param request - source Session and optional exact inclusive event boundary. * @returns the new Session identity. */ @Remote('fork') fork(request: SessionForkRequest): Promise @@ -886,6 +907,14 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' | */ @Remote({ mode: 'stream' }) follow(request: SessionFollowRequest, signal: AbortSignal): AsyncIterable +/** + * Read all registered projections without activating an Agent. + * @param request - Session whose current values are required. + * @param signal - cancellation for the Session observation. + * @returns complete baseline, or null when the Session does not exist. + */ +@Remote('projections') async projections(request: SessionProjectionsRequest, signal: AbortSignal): Promise + /** * Stream a complete live-control baseline followed by replacement frames. * @param signal - cancellation owned by the Remote stream carrier. @@ -1022,10 +1051,12 @@ get(id: SessionId): Session | undefined list(): Session[] /** - * Create a live child session from a stable prefix of a live source. + * Create a live child session from an exact prefix of a live source. * `boundary` is an inclusive source event seq; omitted means the source's - * current last event. The selected slice may end with a between-turn event - * but must not end inside an open turn. + * current last event. An open tail receives synthetic tool results and + * step/turn closers with the forked cause. Closed steps and turns remain + * unchanged, including any failed tool calls already missing results. + * `inheritedEventCount` counts only copied source events, excluding these closers. * * @param source - Live source session object or id. * @param boundary - Inclusive source event seq to fork through; omitted means @@ -1070,13 +1101,14 @@ Source: [`packages/api/session-controller/src/types.ts`](../../packages/api/sess #### `api-session/added` — emit -A Session became visible to Session list consumers. +A Session became visible or its Agent was created or disposed. Consumers upsert the summary and replace its current running and availability state. ```ts cordis-catalog /** - * A Session became visible to Session list consumers. + * A Session became visible or its Agent was created or disposed. + * Consumers upsert the summary and replace its current running and availability state. * @mode emit - * @param summary - initial list row for the Session. + * @param summary - current list row for the Session. */ 'api-session/added'(summary: SessionSummary): void ``` diff --git a/docs/subsystems/session.zh.md b/docs/subsystems/session.zh.md index 56a0502fcb..7cd3c38162 100644 --- a/docs/subsystems/session.zh.md +++ b/docs/subsystems/session.zh.md @@ -11,8 +11,8 @@ 仅追加的事件类型。可通过声明合并扩展:插件通过 declaration merging 声明额外的事件类型。例如[压缩(compaction) seam](compaction.zh.md) 添加了 `compaction/start` / `compaction/summary` / `compaction/end`,`@deepseek-ai/dsh-hook-protocol` 为钩子桥接添加了仅记录日志的 `hook/invoked` / `hook/result` 记录。与 `compaction/*` 一样,这些都不是 `SurfaceEventType`(没有 `surfaceOp`)。生成的[持久化日志事件目录](../persistence-catalog.zh.md)列举了所有成员(核心与合并扩展的),包含其 payload、surface 标记与声明位置。 ```ts type-equiv -/** A user-role specialization of the one shared message representation. */ -interface UserMessage extends Message { +/** A user-role specialization of the shared message representation. */ +interface UserMessage extends MessageBase { readonly role: 'user' } ``` @@ -53,6 +53,14 @@ interface SessionEventMap { * project their `content` verbatim; `source` tells them apart. */ 'user/message': UserMessage + /** An incremental agent session change admitted at the named turn and step. */ + 'developer/message': { + turn: number + step: number + message: DeveloperMessage + /** Earlier request/header defining every tool addition; required exactly when additions are present. */ + headerSeq?: SessionSeq + } /** * The rendered system prompt on the model-visible surface. The loop appends * the first one as surface node 0 before the step's first `user/message`. @@ -116,7 +124,7 @@ interface SessionEventMap { message: ToolResultMessage /** * Optional failure identity and raw user-facing reason, outside model content; - * allowed only when the tool-result block has `isError: true`. + * allowed only when the message has `isError: true`. */ error?: { name: string; code: string; reason?: string } meta?: JsonValue @@ -139,19 +147,21 @@ interface SessionEventMap { */ 'request/context': RequestContext /** - * Marks the end of a constructor seed. Events before it have smaller seq - * values and came from the seed (resume, fork, or replay); this lifecycle - * produced none of them. This log-only event is the durable projection of - * {@link Session.firstLiveSeq}. + * Separates inherited or restored history from later lifecycle-owned work. + * This log-only marker need not be at {@link Session.firstLiveSeq}: a fork + * seed can already contain its tagged marker and child-owned synthetic + * closers before construction. * * A fresh fork child owns one `{ inherited: true }` marker at its exact * inherited-prefix cut, even when that prefix ends in an ancestor marker. - * The last tagged marker is the current Session's cut; untagged markers keep - * ordinary restore and replay lifecycle boundaries. + * `buildForkSeed` appends that marker before any synthetic closers; the + * `Session` constructor supplies it when given only the inherited prefix. + * The last tagged marker is the current Session's cut; untagged markers + * keep ordinary restore and replay lifecycle boundaries. * - * `Session`'s constructor is the only legitimate writer. The invariant - * companion deliberately constrains nothing here, so a plugin appending one - * would silently classify every live bracket before it as seed history. + * Only the `Session` constructor and `buildForkSeed` may create this marker. + * The invariant companion deliberately constrains nothing here, so a plugin + * appending one would silently classify every live bracket before it as seed history. * * An owner of a standalone open/close bracket (`compaction/start` … * `compaction/end`) reads it because seed history and live work are otherwise @@ -186,6 +196,10 @@ interface EpochHeader { adapterDefaults?: LlmCallConfigAdapterDefaults /** Assembled tool schemas; absent for a tool-less request. */ tools?: ToolSchema[] + /** Retired request text; system prompts belong to system/message events. + * @persistenceReserved + */ + system?: never } ``` @@ -277,13 +291,13 @@ type SessionEvent = { `SessionEventType = keyof SessionEventMap`。由于 `SessionEventMap` 可通过合并扩展,对 `SessionEvent` 的 switch 语句禁止使用 `assertNever`:插件添加的变体是合法的未知值;处理已知 case 后在 `default` 中放行。 -每个 surface 事件都要求 `surfaceOp`;已知仅日志事件禁止两个 surface 元数据字段。原生未知或已退役的可忽略信封保持不透明。`assistant/message` 嵌入其提供方 stream,并禁止 `sourceEventSeqs`。System、user 与 tool surface 事件可以在来源归属或替换覆盖需要时引用完整、非空且唯一的较早事件集合。`tool/result` 仅在工具结果块带有 `isError: true` 时可以携带 `data.error`;失败结果的失败身份仍可省略。 +每个 surface 事件都要求 `surfaceOp`;已知仅日志事件禁止两个 surface 元数据字段。原生未知或已退役的可忽略信封保持不透明。`assistant/message` 嵌入其提供方 stream,并禁止 `sourceEventSeqs`。System、user 与 tool surface 事件可以在来源归属或替换覆盖需要时引用完整、非空且唯一的较早事件集合。`tool/result` 仅在消息带有 `isError: true` 时可以携带 `data.error`;失败结果的失败身份仍可省略。 ## Surface 类型 -四种产生消息的类型(`SurfaceEventType`:`system/message`、`user/message`、`assistant/message`、`tool/result`)携带 surface 元数据,用来声明它们如何加入有序的派生 surface。`system/message` 承载渲染后的系统提示词:循环把第一条追加为 surface 第 0 号节点,并在提示词变化时恰好替换最新的系统节点,或在历史内路由上追加一条新的;surface 折叠拒绝任何其他覆盖第 0 号节点 `system/message` 的替换,而后续系统节点是普通历史,压缩替换可以遮蔽它。见 [session surface Agent Note](../../.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md)。 +产生消息的类型(`SurfaceEventType`:`system/message`、`developer/message`、`user/message`、`assistant/message`、`tool/result`)携带 surface 元数据,用来声明它们如何加入有序的派生 surface。`system/message` 承载渲染后的系统提示词:循环把第一条追加为 surface 第 0 号节点,并在提示词变化时恰好替换最新的系统节点,或在历史内路由上追加一条新的;surface 折叠拒绝任何其他覆盖第 0 号节点 `system/message` 的替换,而后续系统节点是普通历史,压缩替换可以遮蔽它。见 [session surface Agent Note](../../.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md)。 ### `SurfaceEventType`:事件类型中产生消息的子集 @@ -296,6 +310,7 @@ type SessionEvent = { */ type SurfaceEventType = | 'system/message' + | 'developer/message' | 'user/message' | 'assistant/message' | 'tool/result' @@ -460,29 +475,26 @@ declare class Session { /** The session identity, derived from its durable header's single copy. */ get id(): SessionId; /** - * The first seq appended IN THIS PROCESS: the length of the constructor - * seed (0 without one). Events with smaller seq values entered through - * construction — replay, fork, or resume — and were never published on the - * `session/event` firehose (constructor seeds do not emit). This offset marks - * the constructor-input boundary for lifecycle ownership and persistence - * adoption; consumers that need complete canonical history still start at - * seq 0. Distinct from {@link inheritedEventCount}, the DURABLE - * fork-lineage cut: a resumed session's constructor seed is its full stored - * log, while the inherited count keeps the original fork value — this field is the - * in-process construction fact. + * The constructor seed length (0 without one), before any marker appended + * during construction. Seed events never publish on `session/event`. A + * marker appended before the store attaches occupies this seq without + * publishing either; otherwise this seq is available for the next append. * - * Not persisted itself: a seeded session projects it into the log as the - * `session/end-seed` event, which is what a consumer reading STORED history - * reads. Locate the LAST such event, not necessarily one at this seq — a - * seed already ending in one is not re-marked, so reopening an untouched - * session leaves that event at a smaller seq than `firstLiveSeq`. Prefer - * this field in-process: it is exact before the marker reaches storage. - * - * When this lifecycle appends the marker, it occupies this seq before the - * store attaches and therefore does not publish either. Otherwise this seq - * holds an ordinary published write. + * This in-process offset is not persisted. A fork seed can already contain + * the child's inherited marker and synthetic closers, so its child-owned + * history starts at {@link inheritedEventCount}, before this offset. A + * resumed Session's seed contains its full stored log, while its inherited + * count keeps the durable fork cut. Consumers needing complete canonical + * history start at seq 0. */ readonly firstLiveSeq: SessionLogOffset; + /** + * First event produced for this object lifecycle. A new fork includes its + * child-owned seed marker and closers; a restored Session starts after its + * complete stored prefix. This in-process capture offset is not persisted. + */ + readonly firstLifecycleSeq: SessionLogOffset; + /** * Create a detached session by validating and snapshotting borrowed seed * events and storage metadata. @@ -653,7 +665,7 @@ declare class Session { - `user/message` → 一条携带确切 `content` 的 user 消息;可选 envelope 仅作为日志中的展示元数据保留。 - `assistant/message` → 一条 assistant 消息,包含生成它的提供方和模型,以及可选的适配器私有回放状态。其嵌入式紧凑 stream 是回放、usage 与 UI 证据,而不是第二条 message。**内容为空的** `assistant/message` 也会跳过:因 max-tokens 而截断且无内容的步骤仍会记录一条 `assistant/message` 来保存 stream、usage、提供方和模型,但无内容的 assistant 轮次不得进入提供方 transcript(文本记录)。 -- `tool/result` → 一条携带 `tool-result` 块的 user 消息。 +- `tool/result` → 一条一等 tool-role 消息,携带结果内容与工具调用标识。 - `user/message`(注入上下文,即非 `user` 来源)→ 按时间顺序在相应位置生成一条 user-role 消息,并原样承载其 `content`;其类型化 source 标明生产方,并携带所有生产方专用数据。 其余所有事件(`turn/*`、`step/*`、`assistant/attempt`、插件所属的 `llm/retry`)均为结构信息,不会投影为消息。token 记账会展开每个 `assistant/message` 或 `assistant/attempt` 的嵌入式 stream,message 顶层 `usage` 存在时仍是已提交 message 的权威。失败的模型请求 attempt 因此可以保留提供方 usage,而无需虚构 assistant message。当前逻辑校验会拒绝没有提供方/模型的 request header 和 assistant 消息,而不会猜测路由;受支持的历史表示会在当前 Session 存在前,由其相邻格式迁移边归一化并校验。 @@ -702,10 +714,17 @@ interface TurnEndReasonMap { * the events recorded before the crash remain intact. */ interrupted: { kind: 'interrupted' } + /** + * Fork-seed construction closed a turn that was still open at the fork + * boundary in the source session. Only fork seeds carry this marker — the + * loop never emits it — and the source events before the boundary remain + * intact in the child. + */ + forked: { kind: 'forked' } } ``` -`max-tokens` 与模型调用中同名的 `FinishReason` 对应:只要轮次内有任何步骤以 `max-tokens` 结束,整个轮次就以 `max-tokens` 而不是 `completed` 结束(即使之后继续执行,截断事实仍优先),让消费方能够区分正常停止和截断停止。取消和错误仍是不同的结果。`interrupted` 是唯一不会由任何 loop 发出的原因:它由崩溃恢复合成(见 [persistence.md](persistence.zh.md))。该 map 可通过合并扩展。 +`max-tokens` 与模型调用中同名的 `FinishReason` 对应:只要轮次内有任何步骤以 `max-tokens` 结束,整个轮次就以 `max-tokens` 而不是 `completed` 结束(即使之后继续执行,截断事实仍优先),让消费方能够区分正常停止和截断停止。取消和错误仍是不同的结果。loop 不会实时发出 `interrupted` 或 `forked`:崩溃恢复合成 `interrupted`(见 [persistence.md](persistence.zh.md)),而 fork 种子构造合成 `forked`。该 map 可通过合并扩展。 ## 执行封闭与独立事件 @@ -715,7 +734,7 @@ interface TurnEndReasonMap { ## 种子结束边界:`session/end-seed` -新 fork constructor 要求 seed 等于 inherited prefix,并在精确持久 cut 追加 `session/end-seed { inherited: true }`。restore 会保留该 tagged marker,并且只在完整 stored seed 尚未以 marker 结尾时追加普通 `session/end-seed {}`。两种形式都只进入 log 且不产生 message;`Session` constructor 是唯一合法 writer。 +`buildForkSeed` 在精确的 inherited-prefix cut 追加 `session/end-seed { inherited: true }`,然后添加合成的 fork 结束事件。`Session` constructor 保留该预先构造的 marker,或在 seed 仅含 inherited prefix 时追加 marker。restore 保留 tagged marker,并且只在完整 stored seed 尚未以 marker 结尾时追加普通 `session/end-seed {}`。两种形式都只进入 log 且不产生 message;只有 constructor 和 `buildForkSeed` 可以创建它们。 对于 fork lineage,定位 payload 携带 `inherited: true` 的最后一个 marker;当前格式 decoding 只在 `SessionHeader.isSeeded` 为 true 时要求该 marker,并从其 seq 推导 `inheritedEventCount`。对于 lifecycle ownership,定位任一形式的最后一个 `session/end-seed`。重新打开已经以任一 marker 结尾的 seed 时,不会再追加普通 marker。 @@ -838,8 +857,10 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' | @Remote('rename') rename(request: SessionRenameRequest): Promise /** - * Fork one cold-readable completed-turn prefix into a new Session. - * @param request - source Session and optional event anchor. + * Fork one cold-readable exact event prefix into a new Session. An omitted + * boundary selects the latest completed-turn prefix; an open cut receives + * synthetic fork closers. + * @param request - source Session and optional exact inclusive event boundary. * @returns the new Session identity. */ @Remote('fork') fork(request: SessionForkRequest): Promise @@ -890,6 +911,14 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' | */ @Remote({ mode: 'stream' }) follow(request: SessionFollowRequest, signal: AbortSignal): AsyncIterable +/** + * Read all registered projections without activating an Agent. + * @param request - Session whose current values are required. + * @param signal - cancellation for the Session observation. + * @returns complete baseline, or null when the Session does not exist. + */ +@Remote('projections') async projections(request: SessionProjectionsRequest, signal: AbortSignal): Promise + /** * Stream a complete live-control baseline followed by replacement frames. * @param signal - cancellation owned by the Remote stream carrier. @@ -1026,10 +1055,12 @@ get(id: SessionId): Session | undefined list(): Session[] /** - * Create a live child session from a stable prefix of a live source. + * Create a live child session from an exact prefix of a live source. * `boundary` is an inclusive source event seq; omitted means the source's - * current last event. The selected slice may end with a between-turn event - * but must not end inside an open turn. + * current last event. An open tail receives synthetic tool results and + * step/turn closers with the forked cause. Closed steps and turns remain + * unchanged, including any failed tool calls already missing results. + * `inheritedEventCount` counts only copied source events, excluding these closers. * * @param source - Live source session object or id. * @param boundary - Inclusive source event seq to fork through; omitted means @@ -1074,13 +1105,14 @@ Source: [`packages/api/session-controller/src/types.ts`](../../packages/api/sess #### `api-session/added` — emit -A Session became visible to Session list consumers. +A Session became visible or its Agent was created or disposed. Consumers upsert the summary and replace its current running and availability state. ```ts cordis-catalog /** - * A Session became visible to Session list consumers. + * A Session became visible or its Agent was created or disposed. + * Consumers upsert the summary and replace its current running and availability state. * @mode emit - * @param summary - initial list row for the Session. + * @param summary - current list row for the Session. */ 'api-session/added'(summary: SessionSummary): void ``` diff --git a/docs/subsystems/subagent.i18n.yaml b/docs/subsystems/subagent.i18n.yaml index 0cea3b7d31..034d835426 100644 --- a/docs/subsystems/subagent.i18n.yaml +++ b/docs/subsystems/subagent.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/subagent.md -subagent.md: 32c9d47c288a352ef234a0e555484d3826f6adf5 -subagent.zh.md: 2e39072f820e3e4c5afc2884babbde63e23af7df +subagent.md: d642fe1658926b17cb29f280803f12e61228be60 +subagent.zh.md: ff153c7861b4ac46bb058efd00a2f5a50181b6f2 diff --git a/docs/subsystems/subagent.md b/docs/subsystems/subagent.md index 32c9d47c28..d642fe1658 100644 --- a/docs/subsystems/subagent.md +++ b/docs/subsystems/subagent.md @@ -4,7 +4,7 @@ English | [中文](subagent.zh.md) The subagent seam lets an agent delegate work to a child agent. Like [bash](shell.md), it is **one optional capability**, not part of the agent loop, so its types live here rather than in [core.md](core.md). It differs from the other capability seams because **multiple provider implementations coexist** in one context, registered by name (`ctx.subagents`), while bash allows only one executor. Its registry follows the [LLM adapter registry](llm-streaming.md), not the single-service bash executor. -Service Definition: [dsh-subagent](../../packages/subagent/subagent) (`ctx.subagents` + the vocabulary below). Service Providers are sibling packages (`dsh-subagent-spawn-in-process`, `dsh-subagent-fork-in-process`, `dsh-subagent-acp`, `dsh-subagent-codex`, `dsh-subagent-claude-code`, `dsh-subagent-dsh-sdk`); the model-facing Consumers are [dsh-tool-subagent](../../packages/subagent/tool-subagent) (per-provider delegation) and [dsh-tool-subagent-control](../../packages/subagent/tool-subagent-control) (the optional global `send_message`, `interrupt_agent`, and `list_agents` controls). The same `ctx.subagents` service owns continuable-child orchestration through an internal activation manager and read-only child and descendant discovery straight from the session store and optional session persistence. Product-provider rationale lives in [the Codex and Claude Code Agent Note](../../.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md); common-seam rationale lives in [the subagent Agent Note](../../.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md), [the continuable subagents Agent Note](../../.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md), and [the adjacent-Agent messaging Agent Note](../../.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.md); [the archived list-identity-projection record](../../.agents/notes/archived/architecture/2026-08-06-subagent-list-identity-projection.md) documents the original list-identity decision. +Service Definition: [dsh-subagent](../../packages/subagent/subagent) (`ctx.subagents` + the vocabulary below). Service Providers are sibling packages (`dsh-subagent-spawn-in-process`, `dsh-subagent-fork-in-process`, `dsh-subagent-acp`, `dsh-subagent-codex`, `dsh-subagent-claude-code`, `dsh-subagent-dsh-sdk`); the model-facing Consumers are [dsh-tool-subagent](../../packages/subagent/tool-subagent) (per-provider delegation) and [dsh-tool-subagent-control](../../packages/subagent/tool-subagent-control) (the optional global `send_message`, `interrupt_agent`, and `list_agents` controls). The same `ctx.subagents` service owns continuable-child orchestration through an internal activation manager, direct-child discovery through the parent catalog, and complete descendant discovery through the Session corpus. Product-provider rationale lives in [the Codex and Claude Code Agent Note](../../.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md); common-seam rationale lives in [the subagent Agent Note](../../.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md), [the continuable subagents Agent Note](../../.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md), and [the adjacent-Agent messaging Agent Note](../../.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.md); [the archived list-identity-projection record](../../.agents/notes/archived/architecture/2026-08-06-subagent-list-identity-projection.md) documents the original list-identity decision. Sources: [`packages/subagent/subagent/src/types.ts`](../../packages/subagent/subagent/src/types.ts), [`packages/subagent/subagent/src/index.ts`](../../packages/subagent/subagent/src/index.ts), and [`packages/subagent/subagent/src/continuation.ts`](../../packages/subagent/subagent/src/continuation.ts) @@ -266,7 +266,9 @@ A local one-shot provider appends the descriptor inside the child's initial turn ## Durable enumeration: `listChildren()`, `listDescendants()`, and their entries -`SubagentRuntime.listChildren(parentSessionId)` enumerates the parent's direct session-backed subagents from the live-preferred merge of `ctx.sessions` and the session-query engine's `listSessions()` — no Agent is loaded or resumed. Candidates are the direct children whose durable header carries `origin: 'subagent'`; the marker classifies enumeration and coarse generic-route denial but cannot establish a valid descriptor, resumability, or authorization — the projection fold owns identity, and the Activation contract owns resume. Each row's `mode`/`label` is the registered `subagent` projection unit's value, served through a three-rung ladder: the registry's watermark cache for a live child (zero log reads); the optional projection checkpoint cache for a cold one (`cachedSnapshot` — an identity passing the own-suffix seq gate is final, because an own descriptor is immutable once appended); otherwise one `query.observeSession()` cold observation folded through the registry (bounded concurrency, recomputed per listing). The cache is a pure optional accelerator: absent, serving the `null` sentinel or missing the key, failing the seq gate, or faulting, it falls silently through to the authoritative refold. The fold is `subagent/descriptor` last-wins with no failure channel: the child's own descriptor overrides a fork-seeded ancestor's, and a malformed or unknown-version payload folds to a serializable `null` sentinel, treated as no value. The result is one `SubagentListEntry[]` in `createdAt`-then-id order: a served identity yields a `child` entry with `mode: 'one-shot' | 'continuable'` and `activity: 'running' | 'inactive'`; continuable entries always carry `label`, while one-shot entries carry it only when the start caller supplied presentation metadata. A settled candidate whose fold served no identity yields a `corrupt` diagnostic — missing, malformed, and unknown-version descriptors deliberately undistinguished (`unsupported` remains in the type but is never produced); a running candidate without an identity is omitted (the creation window before its descriptor lands); a failed cold inspection yields one `unavailable` diagnostic retried on the next listing, so one damaged sibling cannot hide healthy children. `hasChildren` marks a direct descendant with durable subagent origin, read from the same merged material. Activity snapshots only whether the logical record is live in `ctx.sessions`, not outcome or resumability. Absent persistence, enumeration is live-only rather than an error — a cold child cannot be resumed then either. `listChildren()` throws `SubagentError` with code `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` when the `ctx.sessionProjections` registry is absent and `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE` when the session store is, both checked before any read so a deployment with zero children still fails deterministically; the list tool requires `ctx.subagents` and `ctx.agents` at plugin load. A service consumer such as a UI can display both modes and choose an unlabeled one-shot fallback, while the model-facing `list_agents` adapter (the separately loadable `/list-agents` plugin of [dsh-tool-subagent-control](../../packages/subagent/tool-subagent-control)) keeps only continuable entries and refines status through the live Agent registry into `running`/`inactive`; `inactive` includes loaded and storage-only children without describing task completion or outcome. Listing does not consult the continuation manager's Activation map, Agent registry, or provider availability; `send_message` remains the authoritative delivery-time operation, and a listed running continuable child may still reject delivery as an ownership conflict. [The archived list-identity-projection record](../../.agents/notes/archived/architecture/2026-08-06-subagent-list-identity-projection.md) documents the original read-path decision. +The model-facing `list_agents` adapter reports current activity as `running` or `inactive`. These values do not describe task completion or guarantee that `send_message` will succeed. + +`SubagentRuntime.listChildren(parentSessionId, signal?)` reads the parent's `subagentCatalog` view through a live-preferred Session observation and releases that observation on success or failure. It returns direct-child entries in parent event order without reading child logs or enumerating the Session corpus. Query failures propagate; a missing catalog projection fails explicitly. Browser rows derive membership from the shared projection store and add activity from Session status; the control stream pushes complete catalog updates. `listDescendants()` retains corpus traversal, child-identity diagnostics, and complete `hasChildren` computation. [The parent-catalog Agent Note](../../.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md) owns creation, fork isolation, ordering, and persistence costs. `SubagentRuntime.listDescendants(rootSessionId)` applies the same live-preferred corpus and projection-backed interpretation to the root's complete descendant tree in stable pre-order. Ordinary sessions and one-shot children remain traversal nodes, so continuable descendants below them are discovered; only `origin: 'subagent'` candidates produce rows. Each returned child or diagnostic adds its position from the enumerated durable header, while a cold inspection revalidates that complete lifecycle before serving identity: @@ -300,7 +302,7 @@ interface SubagentResult { * are skipped. Without a non-empty message, the output is its accumulated * assistant text stream, or `[]` when the child produced neither. */ - readonly output: ContentBlock[] + readonly output: readonly ContentBlock[] /** * The structured result after a requested `outputSchema` was successfully * satisfied. Requesting a schema does not guarantee presence: a provider can @@ -463,6 +465,8 @@ The spawn and fork backends create an ordinary one-shot agent through `parent.ct - **Delegation depth** is durable `SessionHeader.delegationDepth` plus the merge-extensible runtime field `AgentOptions.subagentDepth`; absence means top-level depth zero, and the greater present value is authoritative. The seam owns both fields — the loop neither sets nor reads them — so an in-process child persists parent depth + 1, cold resume cannot lower it, and every start rejects a derived depth outside the safe-integer domain or above a defined absolute `request.maxDepth` cap. - **Fork seeding** uses [`CreateAgentOptions.seed`](core.md#creation-and-ownership) (a `SessionEvent[]` prefix threaded through `AgentLoop.createAgent` → `ctx.sessions.prepare({ seed })`, the same primitive `ctx.agents.resume()` uses). The fork backend passes a *balanced completed-turn prefix* of the parent's log — the parent's events up to and including its last `turn/end` — so the seed is contiguous-from-0 and the [invariants](../../packages/runtime-diagnostics/invariants) replay accepts it (the in-flight, unbalanced turn is excluded). +`SubagentCatalogEntry` describes one successful direct-child creation fact; `SubagentCatalogState` is the host-only projection state. `listChildren()` owns a live-preferred parent observation without opening child logs. Browser consumers read `subagentCatalog` through the shared Session projection store and combine membership with Session-list activity. `SubagentCatalogRow` belongs to complete-descendant listing. [The parent-catalog decision](../../.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md) owns the persistent facts and read semantics. + @@ -570,23 +574,15 @@ async drainContinuableDescendants(parents: readonly Agent[]): Promise async drainContinuableChildren(parent: Agent, childIds: readonly SessionId[]): Promise /** - * Enumerate the parent's direct session-backed subagents without loading or - * resuming an Agent. The Session query service supplies one live-preferred - * corpus and shared point observations; the projection cache supplies - * immutable descriptor hits without opening cold logs. The registered - * `subagent` projection remains the sole mode/label classifier. - * - * Every query receives `signal`, and the listing rechecks cancellation - * around each await. Read rejections that settle - * after an abort become a stable `SubagentError` with code `CANCELLED`. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - caller-owned cancellation forwarded to Session queries - * and observed around every read await. - * @returns children and per-child diagnostics ordered by `createdAt`, then id. - * @throws {@link SubagentError} when the projection registry or the session - * store is not mounted, or the caller cancels the listing. + * Read the parent's durable direct-child catalog without loading or resuming an Agent. + * The service owns and releases the live-preferred Session observation. + * @param parentSessionId - parent whose direct children are requested. + * @param signal - cancellation forwarded to the Session query. + * @returns catalog children in parent event order. + * @throws {@link SubagentError} when query or catalog projection is unavailable. + * @throws SessionQueryError when the parent cannot be read or the query is cancelled. */ -listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise +listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise /** * Enumerate the root's complete session-backed subagent tree in stable @@ -594,32 +590,17 @@ listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise -/** - * Remote face of {@link listChildren} for one browser: the durable listing - * plus live Agent activity and the delivery-time parent availability hint. - * Parent availability is a hint; {@link prompt} performs the authoritative - * check. Named apart from the provider-name {@link list}, which owns the - * member. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - carrier cancellation forwarded to Session queries. - * @returns the catalog view for that parent. - * @throws {RemoteError} `gateway/bad-request` for an empty parent id, - * `gateway/cancelled` for an aborted read, `subagent/projections-unavailable` when - * the deployment has no projection registry, otherwise `gateway/internal`. - */ -@Remote('list') async remoteExportList(parentSessionId: SessionId, signal: AbortSignal): Promise - /** * Deliver one browser-authored message to a continuable child through the * exact live direct parent, retaining the caller-minted request identity and diff --git a/docs/subsystems/subagent.zh.md b/docs/subsystems/subagent.zh.md index 2e39072f82..ff153c7861 100644 --- a/docs/subsystems/subagent.zh.md +++ b/docs/subsystems/subagent.zh.md @@ -4,7 +4,7 @@ subagent seam 让一个 agent(智能体)将工作委派给子 agent。与 [bash](shell.zh.md) 一样,它是**一项可选能力**,不属于 agent loop(智能体循环),因此其类型定义在此而非 [core.md](core.zh.md) 中。它不同于其他能力 seam,因为**同一上下文中可共存多个提供方实现**,并按名称注册(`ctx.subagents`),而 bash 只允许一个执行器。该注册表遵循 [LLM(大语言模型)适配器注册表](llm-streaming.zh.md),而非单服务的 bash 执行器。 -Service Definition:[dsh-subagent](../../packages/subagent/subagent)(`ctx.subagents` + 下文词汇)。Service Provider 是六个兄弟包:`dsh-subagent-spawn-in-process`、`dsh-subagent-fork-in-process`、`dsh-subagent-acp`、`dsh-subagent-codex`、`dsh-subagent-claude-code`、`dsh-subagent-dsh-sdk`;面向模型的 Consumer 包括 [dsh-tool-subagent](../../packages/subagent/tool-subagent)(按提供方委派)和 [dsh-tool-subagent-control](../../packages/subagent/tool-subagent-control)(可选的全局 `send_message`、`interrupt_agent` 与 `list_agents` 控制工具)。同一个 `ctx.subagents` 服务通过内部激活管理器负责可继续子 agent 编排,并直接基于会话存储和可选的会话持久化提供只读的 child 与后代发现。产品提供方设计理由见 [Codex 与 Claude Code Agent Note](../../.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.zh.md);通用 seam 的设计理由见 [subagent Agent Note](../../.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.zh.md)、[可继续 subagent Agent Note](../../.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.zh.md)和[相邻 Agent 消息 Agent Note](../../.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.zh.md);[已归档的列表身份投影记录](../../.agents/notes/archived/architecture/2026-08-06-subagent-list-identity-projection.md)记录了最初的列表身份决策。 +Service Definition:[dsh-subagent](../../packages/subagent/subagent)(`ctx.subagents` + 下文词汇)。Service Provider 是六个兄弟包:`dsh-subagent-spawn-in-process`、`dsh-subagent-fork-in-process`、`dsh-subagent-acp`、`dsh-subagent-codex`、`dsh-subagent-claude-code`、`dsh-subagent-dsh-sdk`;面向模型的 Consumer 包括 [dsh-tool-subagent](../../packages/subagent/tool-subagent)(按提供方委派)和 [dsh-tool-subagent-control](../../packages/subagent/tool-subagent-control)(可选的全局 `send_message`、`interrupt_agent` 与 `list_agents` 控制工具)。同一个 `ctx.subagents` 服务通过内部激活管理器负责可继续子 agent 编排,通过 parent 目录发现直接 child,并通过 Session 语料库发现完整后代。产品提供方设计理由见 [Codex 与 Claude Code Agent Note](../../.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.zh.md);通用 seam 的设计理由见 [subagent Agent Note](../../.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.zh.md)、[可继续 subagent Agent Note](../../.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.zh.md)和[相邻 Agent 消息 Agent Note](../../.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.zh.md);[已归档的列表身份投影记录](../../.agents/notes/archived/architecture/2026-08-06-subagent-list-identity-projection.md)记录了最初的列表身份决策。 源码:[`packages/subagent/subagent/src/types.ts`](../../packages/subagent/subagent/src/types.ts)、[`packages/subagent/subagent/src/index.ts`](../../packages/subagent/subagent/src/index.ts)和 [`packages/subagent/subagent/src/continuation.ts`](../../packages/subagent/subagent/src/continuation.ts) @@ -266,7 +266,9 @@ interface ContinuableCreateSpec { ## 持久化枚举:`listChildren()`、`listDescendants()` 与其条目 -`SubagentRuntime.listChildren(parentSessionId)` 从 `ctx.sessions` 与会话查询引擎 `listSessions()` 的实时优先合并中枚举 parent 直接且由会话支撑的 subagent——不会加载或恢复任何 Agent。候选是持久 header 携带 `origin: 'subagent'` 的直接 child;该标记只负责枚举分类与粗粒度的通用路由拒绝,不能证明描述符有效、child 可恢复或操作已获授权——身份由投影折叠负责,恢复由 Activation 约定负责。每行的 `mode`/`label` 是已注册 `subagent` projection unit 的值,经三级阶梯供值:存活 child 由注册表水位缓存供值(零日志读取);冷 child 先读可选的投影 checkpoint 缓存(`cachedSnapshot`——过 own-suffix seq 门的身份即定值,own descriptor 一经追加不可变);否则在一次 `query.observeSession()` 冷观察上经注册表折叠(有界并发,每次列表重新计算)。该缓存是纯可选加速层:服务缺席、行里是 `null` 哨兵或 key 缺席、seq 门不过、读取出错,都静默落到权威重折。折叠规则是 `subagent/descriptor` last-wins 且没有失败通道:子 agent 自己的描述符覆盖 fork seed 中祖先的描述符,格式错误或版本不认识的载荷折叠为可序列化的 `null` 哨兵,视同无值。结果是按 `createdAt`、再按 id 排序的 `SubagentListEntry[]`:取到身份即生成带有 `mode: 'one-shot' | 'continuable'` 和 `activity: 'running' | 'inactive'` 的 `child` 条目;可继续条目始终携带 `label`,一次性条目则只在启动调用方提供展示元数据时携带该字段。已定局而折叠无身份的候选生成 `corrupt` diagnostic——缺失、格式错误与版本不认识的描述符有意不再细分(`unsupported` 仍保留在类型中但从不产出);运行中而无身份的候选被省略(描述符落盘前的创建窗口);冷检查失败生成一条 `unavailable` diagnostic 并在下次列表自然重试,因此一个损坏的 sibling 不会隐藏健康 child。`hasChildren` 标记存在持久 subagent origin 的直接后代,读取自同一份合并材料。活动状态只表示逻辑记录是否在 `ctx.sessions` 中存活,而不表示结果或可恢复性。缺少持久化时,枚举退化为仅存活枚举而不是报错——此时冷 child 本就无法恢复。缺少 `ctx.sessionProjections` 注册表时,`listChildren()` 抛出携带错误码 `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` 的 `SubagentError`,缺少会话存储时则抛出 `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE`,两者都在任何读取之前检查,因此零 child 的部署同样确定失败;列表工具在插件加载时要求 `ctx.subagents` 与 `ctx.agents`。UI 等服务消费方可以展示两种模式,并为无标签的一次性 child 选择回退展示;面向模型的 `list_agents` 适配器([dsh-tool-subagent-control](../../packages/subagent/tool-subagent-control) 中可单独加载的 `/list-agents` 插件)则只保留可继续条目,并通过在线 Agent 注册表将状态细化为 `running`/`inactive`;`inactive` 包括已加载和仅存于存储的 child,不表示任务完成或结果。枚举不会查询继续执行管理器的 Activation map、Agent 注册表或提供方可用性;`send_message` 仍是消息送达时的权威操作,列表中的运行中可继续 child 仍可能因所有权冲突而拒绝投递。[已归档的列表身份投影记录](../../.agents/notes/archived/architecture/2026-08-06-subagent-list-identity-projection.md)记录了最初的读路径决策。 +模型侧的 `list_agents` 适配器将当前活动表示为 `running` 或 `inactive`。这些值不描述任务完成情况,也不保证 `send_message` 会成功。 + +`SubagentRuntime.listChildren(parentSessionId, signal?)` 通过优先使用在线 Session 的观察读取父会话的 `subagentCatalog` 视图,并在成功或失败时释放观察。它按父会话事件顺序返回直接子级条目,不读取子级日志,也不枚举 Session 语料库。查询失败直接传播;缺少目录投影时显式失败。浏览器条目从共享 projection store 派生成员关系,并从 Session 状态补充活动状态;control stream 推送完整目录更新。`listDescendants()` 保留语料库遍历、子级身份诊断和完整的 `hasChildren` 计算。[父目录 Agent Note](../../.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md) 说明创建、fork 隔离、排序和持久化成本。 `SubagentRuntime.listDescendants(rootSessionId)` 将同一份实时优先语料与基于投影的解释应用到根的完整后代树,并按稳定 pre-order 输出。普通会话和一次性 child 仍作为遍历节点,因此其下的可继续后代仍可发现;只有 `origin: 'subagent'` 的候选会生成条目。每个返回的 child 或 diagnostic 都从枚举所得的持久 header 附加树位置;冷检查在提供身份前还会重新校验完整生命周期: @@ -302,7 +304,7 @@ interface SubagentResult { * are skipped. Without a non-empty message, the output is its accumulated * assistant text stream, or `[]` when the child produced neither. */ - readonly output: ContentBlock[] + readonly output: readonly ContentBlock[] /** * The structured result after a requested `outputSchema` was successfully * satisfied. Requesting a schema does not guarantee presence: a provider can @@ -467,6 +469,8 @@ spawn 和 fork 后端通过 `parent.ctx` 创建一个普通的单次 agent,将 - **委派深度**由持久 `SessionHeader.delegationDepth` 与可合并扩展的运行时字段 `AgentOptions.subagentDepth` 共同表示;缺失表示顶层深度为零,存在的较大值具有权威性。两个字段都归该 seam 所有——循环既不设置也不读取它们——因此进程内子 agent 会持久保存 parent 深度 + 1,冷恢复无法降低深度,而且每次 start 都会拒绝超出安全整数域、或高于已定义绝对 `request.maxDepth` 上限的派生深度。 - **Fork 种子注入**使用 [`CreateAgentOptions.seed`](core.zh.md#creation-and-ownership)(一个 `SessionEvent[]` 前缀,经由 `AgentLoop.createAgent` → `ctx.sessions.prepare({ seed })` 传递,与 `ctx.agents.resume()` 使用的原语相同)。fork 后端传入父级日志的一段*平衡的已完成轮次前缀*——父级事件直到并包括其最后一个 `turn/end`——因此种子从 0 连续,[invariants](../../packages/runtime-diagnostics/invariants) 回放可以接受它(进行中的、未平衡的轮次被排除在外)。 +`SubagentCatalogEntry` 描述一条成功创建直接子级的事实;`SubagentCatalogState` 是仅 host 使用的 projection state。`listChildren()` 拥有一次 live-preferred 父 Session observation,不打开子级日志。浏览器消费者通过共享 Session projection store 读取 `subagentCatalog`,并将成员关系与 Session 列表活动状态组合。`SubagentCatalogRow` 属于完整后代列表。[父目录决策](../../.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md) 规定持久事实与读取语义。 + @@ -574,23 +578,15 @@ async drainContinuableDescendants(parents: readonly Agent[]): Promise async drainContinuableChildren(parent: Agent, childIds: readonly SessionId[]): Promise /** - * Enumerate the parent's direct session-backed subagents without loading or - * resuming an Agent. The Session query service supplies one live-preferred - * corpus and shared point observations; the projection cache supplies - * immutable descriptor hits without opening cold logs. The registered - * `subagent` projection remains the sole mode/label classifier. - * - * Every query receives `signal`, and the listing rechecks cancellation - * around each await. Read rejections that settle - * after an abort become a stable `SubagentError` with code `CANCELLED`. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - caller-owned cancellation forwarded to Session queries - * and observed around every read await. - * @returns children and per-child diagnostics ordered by `createdAt`, then id. - * @throws {@link SubagentError} when the projection registry or the session - * store is not mounted, or the caller cancels the listing. + * Read the parent's durable direct-child catalog without loading or resuming an Agent. + * The service owns and releases the live-preferred Session observation. + * @param parentSessionId - parent whose direct children are requested. + * @param signal - cancellation forwarded to the Session query. + * @returns catalog children in parent event order. + * @throws {@link SubagentError} when query or catalog projection is unavailable. + * @throws SessionQueryError when the parent cannot be read or the query is cancelled. */ -listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise +listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise /** * Enumerate the root's complete session-backed subagent tree in stable @@ -598,32 +594,17 @@ listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise -/** - * Remote face of {@link listChildren} for one browser: the durable listing - * plus live Agent activity and the delivery-time parent availability hint. - * Parent availability is a hint; {@link prompt} performs the authoritative - * check. Named apart from the provider-name {@link list}, which owns the - * member. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - carrier cancellation forwarded to Session queries. - * @returns the catalog view for that parent. - * @throws {RemoteError} `gateway/bad-request` for an empty parent id, - * `gateway/cancelled` for an aborted read, `subagent/projections-unavailable` when - * the deployment has no projection registry, otherwise `gateway/internal`. - */ -@Remote('list') async remoteExportList(parentSessionId: SessionId, signal: AbortSignal): Promise - /** * Deliver one browser-authored message to a continuable child through the * exact live direct parent, retaining the caller-minted request identity and diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml index 2ded2bd962..04a2230cee 100644 --- a/docs/tool-catalog.i18n.yaml +++ b/docs/tool-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/tool-catalog.md -tool-catalog.md: 57db5c0dd5041e71834d0337a7e85473c5632038 -tool-catalog.zh.md: 62603434288254a94ee487db4d918a00b2a6caa7 +tool-catalog.md: 2f5746fc63e73b1caf2692a05ff942c13399e6bc +tool-catalog.zh.md: 6fb80b689ca569834e8f585c765547d23cec50df diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index 57db5c0dd5..2f5746fc63 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -1886,7 +1886,7 @@ Source: [`packages/subagent/tool-subagent-control/src/index.ts`](../packages/sub ### `list_agents` -List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now; inactive means no turn is executing, whether the child is loaded or must be resumed. inactive does not describe task completion, success, failure, or waiting for other agents. A `send_message` steers a running child at its nearest step boundary or starts or resumes a turn for an inactive child, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only. +List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now; inactive means no turn is executing, whether the child is loaded or must be resumed. inactive does not describe task completion, success, failure, or waiting for other agents. A `send_message` steers a running child at its nearest step boundary or starts or resumes a turn for an inactive child, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics only in `descendants` scope. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only. ```json { diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index 6260343428..6fb80b689c 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -1892,7 +1892,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后, ### `list_agents` -按持久 id 和标签列出你的可继续后台 subagent。用它回忆你启动过哪些 subagent,而不是轮询完成情况——subagent 完成时你会被告知。状态来自实时注册表:running 表示 agent 此刻正在工作;inactive 表示没有轮次在执行,包括已加载和需要恢复的 child。inactive 不表示任务完成、成功、失败或等待其他 agent。`send_message` 会在运行中 child 的最近 step 边界 steer 消息,或为 inactive child 启动或恢复轮次,且无论处于哪种状态,直接子级都仍可作为 `send_message` 的目标。该快照并非投递承诺;`send_message` 会执行权威检查,仍可能失败。无法读取的子级会作为诊断信息报告,而不会被静默丢弃。`descendants` 作用域会按稳定的前序顺序遍历你下方的整棵树,并为每个条目标注其持久的直接父会话 id 和深度。只有深度为 1 的条目可以使用 `send_message`;更深的条目只能作为 `interrupt_agent` 的候选目标。 +按持久 id 和标签列出你的可继续后台 subagent。用它回忆你启动过哪些 subagent,而不是轮询完成情况——subagent 完成时你会被告知。状态来自实时注册表:running 表示 agent 此刻正在工作;inactive 表示没有轮次在执行,包括已加载和需要恢复的 child。inactive 不表示任务完成、成功、失败或等待其他 agent。`send_message` 会在运行中 child 的最近 step 边界 steer 消息,或为 inactive child 启动或恢复轮次,且无论处于哪种状态,直接子级都仍可作为 `send_message` 的目标。该快照并非投递承诺;`send_message` 会执行权威检查,仍可能失败。无法读取的子级仅在 `descendants` 作用域中作为诊断信息报告。`descendants` 作用域会按稳定的前序顺序遍历你下方的整棵树,并为每个条目标注其持久的直接父会话 id 和深度。只有深度为 1 的条目可以使用 `send_message`;更深的条目只能作为 `interrupt_agent` 的候选目标。 ```json { diff --git a/package.json b/package.json index 909cdddd11..4486d5435c 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "test:snapshot:record": "DSH_SNAPSHOT=record vitest run --config vitest.snapshot.config.ts --update", "test:snapshot:refresh": "DSH_SNAPSHOT=refresh vitest run --config vitest.snapshot.config.ts", "migrate:packed-session-fixtures": "tsx scripts/migrate-packed-session-fixtures.ts", + "migrate:sessions-to-v4": "tsx scripts/migrate-sessions-to-v4.ts", "test:web": "npm run build && npm run test:web:built", "test:web:refresh": "npm run build && DSH_SNAPSHOT=refresh vitest run --config vitest.web.config.ts", "test:web:built": "vitest run --config vitest.web.config.ts", @@ -166,10 +167,12 @@ "gen-persistence-catalog": "tsx scripts/gen-persistence-catalog.ts", "verify-persistence-catalog": "tsx scripts/gen-persistence-catalog.ts --check", "persistence-changes": "tsx scripts/persistence-changes.ts", + "persistence-review": "tsx scripts/persistence-review.ts", "verify-persistence-changes": "tsx scripts/persistence-changes.ts --check", "verify-persistence-releases": "tsx scripts/persistence-releases.ts", "verify-persistence-formats": "tsx scripts/persistence-formats.ts", "gen-session-format-catalog": "tsx scripts/gen-session-format-catalog.ts", + "verify-v3-event-vocabulary": "tsx scripts/verify-v3-event-vocabulary.ts", "verify-session-format-catalog": "tsx scripts/gen-session-format-catalog.ts --check", "gen-third-party-notices": "tsx scripts/gen-third-party-notices.ts", "verify-third-party-notices": "tsx scripts/gen-third-party-notices.ts --check", diff --git a/packages/acp/acp/src/codec.ts b/packages/acp/acp/src/codec.ts index 151756a03e..09e75257b7 100644 --- a/packages/acp/acp/src/codec.ts +++ b/packages/acp/acp/src/codec.ts @@ -27,7 +27,8 @@ export function turnEndToStopReason(reason: TurnEndReason): StopReason { case 'blocked': case 'error': return 'end_turn' - /* v8 ignore next 2 -- TurnEndReason is closed and every member is handled above */ + /* v8 ignore next 2 -- TurnEndReason is merge-extensible; every live-turn member is + * handled above, and seed-only variants (`forked`) never end an ACP prompt turn. */ default: return 'end_turn' } diff --git a/packages/acp/acp/src/updates.ts b/packages/acp/acp/src/updates.ts index 09687078f1..71ac4f0e42 100644 --- a/packages/acp/acp/src/updates.ts +++ b/packages/acp/acp/src/updates.ts @@ -70,16 +70,16 @@ export async function toolResultUpdate( ctx: Context, event: SessionEvent<'tool/result'>, ): Promise { - const result = event.data.message.content[0] + const message = event.data.message const content: ToolCallContent[] = [] - for (const block of result.content) { + for (const block of message.content) { const converted = await assistantBlockToAcp(ctx, block) if (converted !== undefined) content.push({ type: 'content' as const, content: converted }) } return { sessionUpdate: 'tool_call_update', - toolCallId: result.toolCallId, - status: result.isError === true ? 'failed' : 'completed', + toolCallId: message.toolCallId, + status: message.isError === true ? 'failed' : 'completed', content, } } diff --git a/packages/acp/acp/tests/bridge.spec.ts b/packages/acp/acp/tests/bridge.spec.ts index ad1fa30fac..cd9ede1641 100644 --- a/packages/acp/acp/tests/bridge.spec.ts +++ b/packages/acp/acp/tests/bridge.spec.ts @@ -304,7 +304,7 @@ describe('automation-only ACP bridge', () => { await harness.client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} }) const created = await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] }) const agent = harness.ctx.agents.get(SessionId(created.sessionId))! - agent.session.append('session/title', { title: 'materialized', messageSeqs: [], source: { kind: 'fallback' } }) + agent.session.append('session/title', { title: 'materialized', messageSeqs: [], source: { kind: 'user' } }) await harness.client.closeSession({ sessionId: created.sessionId }) const resumed = await harness.client.resumeSession({ sessionId: created.sessionId, cwd: process.cwd() }) diff --git a/packages/acp/acp/tests/edges.spec.ts b/packages/acp/acp/tests/edges.spec.ts index 073a5893c9..8df1a98ad5 100644 --- a/packages/acp/acp/tests/edges.spec.ts +++ b/packages/acp/acp/tests/edges.spec.ts @@ -1,10 +1,17 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { PROTOCOL_VERSION } from '@agentclientprotocol/sdk' import { createUserMessage, ToolCallId, type StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' import { makeBridgeHarness, textResponse, type BridgeHarness } from './harness.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + function toolCallResponse(): StreamChunk[] { return [ { type: 'block-start', index: 0, blockType: 'reasoning' }, @@ -98,7 +105,7 @@ describe('ACP automation output boundary', () => { const { sessionId } = await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] }) const agent = harness.ctx.agents.get(SessionId(sessionId))! - agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'test' } })) await agent.whenIdle() await vi.waitFor(() => { expect(harness!.updates.at(-1)?.sessionUpdate).toBe('usage_update') }) @@ -133,7 +140,7 @@ describe('ACP automation output boundary', () => { const { sessionId } = await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] }) const agent = harness.ctx.agents.get(SessionId(sessionId))! - agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'test' } })) await agent.whenIdle() await vi.waitFor(() => { expect(warn).toHaveBeenCalledWith(expect.stringContaining('output conversion failed')) }) expect(harness.updates).toEqual([]) diff --git a/packages/acp/acp/tests/turns.spec.ts b/packages/acp/acp/tests/turns.spec.ts index a17223750f..0dffdc5836 100644 --- a/packages/acp/acp/tests/turns.spec.ts +++ b/packages/acp/acp/tests/turns.spec.ts @@ -1,4 +1,5 @@ import { createUserMessage, type StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' import { PROTOCOL_VERSION } from '@agentclientprotocol/sdk' import { SessionId } from '@deepseek-ai/dsh-session' @@ -10,6 +11,12 @@ import { type BridgeHarness, } from './harness.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + async function newSession(harness: BridgeHarness): Promise { await harness.client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} }) return (await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] })).sessionId @@ -188,7 +195,7 @@ describe('ACP prompt lifecycle', () => { harness.ctx.on('agent/inbox/inserted', ({ agent: subject, message }) => { if (subject === agent && message.source.kind === 'user' && !injected) { injected = true - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'context' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'context' }], source: { kind: 'test' } })) } }) @@ -208,7 +215,7 @@ describe('ACP prompt lifecycle', () => { }) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'autonomous work' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) await started @@ -230,7 +237,7 @@ describe('ACP prompt lifecycle', () => { kind: 'enter', messages: [createUserMessage({ content: [{ type: 'text', text: 'rewritten prompt' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })) const sessionId = await newSession(harness) @@ -332,7 +339,7 @@ describe('ACP prompt lifecycle', () => { const agent = harness.ctx.agents.get(SessionId(sessionId))! agent.followup(createUserMessage({ content: [{ type: 'text', text: 'unrelated work' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) await vi.waitFor(() => { expect(harness!.adapter.requests).toHaveLength(1) }) @@ -375,7 +382,7 @@ describe('ACP prompt lifecycle', () => { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'unrelated work' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) await agent.whenIdle() releaseValidation.resolve(undefined) @@ -465,7 +472,7 @@ describe('ACP prompt lifecycle', () => { const agent = harness.ctx.agents.get(SessionId(sessionId))! agent.followup(createUserMessage({ content: [{ type: 'text', text: 'autonomous work' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) await vi.waitFor(() => { expect(agent.session.snapshotEvents().some(event => event.type === 'turn/start')).toBe(true) diff --git a/packages/acp/acp/tests/updates.spec.ts b/packages/acp/acp/tests/updates.spec.ts index 4260afc711..d031770ee1 100644 --- a/packages/acp/acp/tests/updates.spec.ts +++ b/packages/acp/acp/tests/updates.spec.ts @@ -73,14 +73,11 @@ describe('standard ACP update projection', () => { step: 1, message: { id: MessageId('tool-message'), - role: 'user', + role: 'tool', + toolCallId: ToolCallId('call-bad'), + isError: true, source: { kind: 'tool', callId: ToolCallId('call-bad') }, - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('call-bad'), - isError: true, - content: [{ type: 'reasoning', text: 'hidden' }], - }], + content: [{ type: 'reasoning', text: 'hidden' }], }, }, }) diff --git a/packages/api/session-controller/README.i18n.yaml b/packages/api/session-controller/README.i18n.yaml index 273d92d4a4..8ceb4a8da4 100644 --- a/packages/api/session-controller/README.i18n.yaml +++ b/packages/api/session-controller/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/api/session-controller/README.md -README.md: fce650e1d12cdeca3ca199fed54fa741177daf75 -README.zh.md: b88bd7a48ec433a9920c129b37d3a132afa8ede7 +README.md: 228ed88ed20b9f9581496468e47079afd1542e4f +README.zh.md: edebf8bdda249cf0ea6797db7dd77fcfa973074a diff --git a/packages/api/session-controller/README.md b/packages/api/session-controller/README.md index fce650e1d1..228ed88ed2 100644 --- a/packages/api/session-controller/README.md +++ b/packages/api/session-controller/README.md @@ -29,13 +29,15 @@ History pages and follow opening snapshots carry one `{ type: 'event', event: Se The Client journal validates exact V3 event envelopes before publishing follow snapshots, live entries, or history pages. It reuses the browser-safe Session validators for required surface markers, exact replacement endpoints, earlier unique source seqs, embedded Assistant provider metadata, request-header omissions, and tool-error consistency. Invalid records fail without field stripping or normalization; range membership and source existence remain durable-log checks on the Host. -Each endpoint states its activation policy. List reads only stored headers and projection-cache rows: it never calls per-session stat or opens a cold Session body. A current-format cache identity may supply every list hint; a lifecycle-matching predecessor cache may supply only its version-compatible title as a stale display fact, never as an authoritative fold seed. Search, attachment, history pages, log following, skill discovery, and workspace-path opening can inspect persistence without activating an Agent; `canOpenWorkspacePath()` reports native-opening availability without addressing a Session. Cancellation requires live state; queue mutation, model, rename, prompt, and file-reference operations may resolve or resume an ordinary Session. Prompt rejects content with neither non-whitespace text nor an attachment before resolving the Agent or appending Session events; queue edits accept only non-empty text content. Prompt admission consumes opaque receipts from the injected [`fileUploads`](../../client/file-upload/README.md) Host service and resolves every same-Agent receipt before sending the complete ordered content list through `ctx.attachments`. Prompt retries whose `requestId` is already queued or logged return the original acceptance without inserting another message. Create and fork are the only operations that create a new Agent directly. The service applies one preset-aware resume policy and subagent ownership fence to its own methods and to the Typert Agent and Session lookups used by other Remote namespaces. Queue mutation has one narrow exception: a live child whose current projected identity is continuable and comes from its own non-seed suffix accepts the ordinary Edit, Remove, and QueueDock Steer actions across both inbox destinations. One-shot, missing, unknown, corrupt, seed-only, or cold children remain rejected without resume. The skill catalog uses a live Agent when present or the recorded preset's standing scope when cold, so listing never starts an Agent. The authenticated delivery routes use `workspaceDesktop()` for the serving Host name and file-manager behavior. `openWorkspacePath({ path, action: "reveal" })` delegates file-manager navigation to the native adapter; omitting `action` opens the file-type association, including HTML and SVG. Both operations require the composed filesystem to map the requested Host path to the same canonical process path; unmapped remote paths are refused before a native command runs. +Each endpoint states its activation policy. List reads only stored headers and projection-cache rows: it never calls per-session stat or opens a cold Session body. A current-format cache identity may supply every list hint; a lifecycle-matching predecessor cache may supply only its version-compatible title as a stale display fact, never as an authoritative fold seed. Search, attachment, history pages, log following, skill discovery, and workspace-path opening can inspect persistence without activating an Agent; `canOpenWorkspacePath()` reports native-opening availability without addressing a Session. Cancellation requires live state; queue mutation, model, rename, prompt, and file-reference operations may resolve or resume an ordinary Session. Prompt rejects content with neither non-whitespace text nor an attachment before resolving the Agent or appending Session events; queue edits accept only non-empty text content. Prompt admission consumes opaque receipts from the injected [`fileUploads`](../../client/file-upload/README.md) Host service and resolves every same-Agent receipt before sending the complete ordered content list through `ctx.attachments`. Prompt retries whose `requestId` is already queued or logged return the original acceptance without inserting another message. Create and fork are the only operations that create a new Agent directly. The service applies one preset-aware resume policy and subagent ownership fence to its own methods and to the Typert Agent and Session lookups used by other Remote namespaces. Queue mutation has one narrow exception: a live child whose current projected identity is continuable and comes from its own non-seed suffix accepts the ordinary Edit, Remove, and QueueDock Steer actions across both inbox destinations. One-shot, missing, unknown, corrupt, seed-only, or cold children remain rejected without resume. The skill catalog uses a live Agent when present or the recorded preset's standing scope when cold, so listing never starts an Agent. The authenticated delivery routes use `workspaceDesktop()` for the serving Host name and file-manager behavior. `openWorkspacePath({ path, action: "reveal" })` delegates file-manager navigation to the native adapter; omitting `action` opens the file-type association, including HTML and SVG. Both operations require the composed filesystem to map the requested Host path to the same canonical process path; unmapped remote paths are refused before a native command runs. `session.projections` reads one complete baseline through a live-preferred Session observation without activating an Agent. It returns null for a missing Session and serves any registered projection keys. The Client exposes shared values and explicit-read state through `projectionsBySession`; domains select their own keys. Session-list summaries carry `agentAvailable`, updated through existing summary and status events independently of durable projections. Initial reads and live projection frames use the same sequence ordering. Client list rows and resident Sessions use the current `sessionListMetadata` projection to reject stale blank-session hints; recency is the later of the summary timestamp and the projected last user prompt. When SessionManager creates an instance before its list row arrives, it reconciles blankness with metadata already retained for that Session. An opened conversation is therefore not reused by New Session even when an older list response still marks it blank. Explicit-id `session.create` adopts a live Session or resumes a persisted Session while retaining its writer lock. Writer contention returns `session/writer-held`; callers may try another blank without suppressing unrelated failures. `session.list` includes persisted blanks using cached metadata, without opening cold log bodies. -Client list refreshes retain unchanged row objects and reuse the items array when order and values match. Each row's `retainedBy` contains positive local reference-source counts; Host metadata refreshes cannot overwrite them. Cache membership checks use a per-refresh ID set, so reconciliation grows linearly with the current list and retained cache sizes. +Client list refreshes retain unchanged row objects and reuse the items array when order and values match. Each row's `retainedBy` contains positive local reference-source counts; Host metadata refreshes cannot overwrite them. Cache membership checks use a per-refresh ID set, so reconciliation grows linearly with the current list and retained cache sizes. Host summary updates replace running and Agent availability; local create/fork responses only fill missing metadata on existing rows. Removed ordinary Sessions retain projection stores only when their catalogs contain children. + +Projection reads retain loading and failure state independently of their values. Reconnect cancels reads from the previous connection and reloads previously requested projections; live membership updates arrive through the control stream. Parent availability comes from Host summaries and remains unknown until a summary or a successful list baseline establishes it. Address lookup resolves projected children without selecting them or creating scopes. The Client adapter exposes `SessionEventStream`, a Gateway `RemoteJournalStream` bound to one ordinary or direct-subagent address. It opens follow before the initial page, publishes only contiguous `replace`, `prepend`, `append`, and `settle-assistant` changes, and repairs reconnect or sequence gaps through a tail page. Backwards paging has two verbs: `loadOlder()` pulls one 50-message page, and `loadThrough(seq)` — the turn-jump loader — loops 200-message pages until the window covers the target seq, lowering a shared target on repeated calls, stopping on a page that makes no progress, and reporting busy through the same `loadingOlder` snapshot bit. The Web adapter explicitly opts into cursorless Assistant frames: each opening carries the active attempt's `startedAfterSeq`, `nextIndex`, and compact stream, and every stream member becomes a Client-only `assistant/live-chunk` entry ordered between durable cursors. The Host captures a follower-local arrival ordinal with that baseline and suppresses buffered frames at or before the cut; a replacement Agent may restart frame revision at one. A durable `assistant/message` or `assistant/attempt` arriving after an active opening stays staged only when its seq follows `startedAfterSeq` and its Turn and Step match; the matching end type, seq, and index publishes one named settlement delta that retires the attempt's transient rows and adds the durable entry while earlier same-step retries remain visible. Revision, dense-index, or settlement gaps for a known attempt reopen follow, while a controller that missed the start ignores unknown-attempt frames and publishes their durable settlement normally. An abandoned end publishes a settlement delta without a durable entry so its transient rows retire immediately. A durable gap-repair page has no Assistant baseline, so its held notification reopens follow once for a paired page and baseline. Every history record covers exactly its event seq. A business, persistence, or unresolved continuity failure terminates the stream, while only physical carrier loss selects automatic resumption. `SessionControlStream` is a Gateway `RemoteSnapshotStream`; every generation opens with a complete process-local baseline, so reconnect replaces jobs and projection state instead of treating transient values as durable events. At each ready Host generation, a synchronous Client subscription clears retained projection values and watermarks before refreshing queries and restarting the control stream, including Sessions absent from the control baseline. The first control stream waits for generation readiness, so its opening values cannot precede invalidation. Outstanding list responses from the previous generation cannot republish those values. Within a generation, a delayed control baseline cannot overwrite or clear newer list, history, or live values. The durable `inbox` projection carries both pending lists through the same cold-read and reconnect path as other projections. Client Agent contexts provide the identity used by the independent [`fileUpload`](../../client/file-upload/README.md) service; Session objects expose lifecycle, prompt, queue, and history operations rather than file transfer. @@ -44,12 +46,14 @@ The Session object also carries local submission echoes: `session.beginSubmissio The user-invocable `skills/list` metadata includes the winning provider’s optional instruction-file `path`. The composer can preview that file without loading every skill body or activating a cold Agent. -Fork copies history through the selected completed turn, including its `turn/end`. Events after that point, including queued input and model-setting changes, are excluded. An omitted or past-end anchor selects the last completed turn; an anchor inside an unfinished turn is rejected. +Fork copies the exact inclusive event prefix selected by `atSeq`, including a cut inside an open turn. The child records its inherited marker before synthetic fork results and closing events. Omitting `atSeq` selects the latest completed turn and its standalone tail, stopping before the next turn or queued input; a nonexistent event is rejected. The chat action selects a completed turn. A resume blocked by an existing write handle returns `session/writer-held` with the Session id; other resume failures retain `gateway/internal`. `loadThrough(seq)` retains older pages privately until its shared target is covered or loading ends, then publishes the successful pages as one ordered prepend. Live events remain visible while history loads. A later page failure retains the successful prefix; replacing the history window discards buffered pages from the replaced window. Ordinary `loadOlder()` still publishes its single page directly. +Queue edits replace pending content with non-empty text only. + ## Client references diff --git a/packages/api/session-controller/README.zh.md b/packages/api/session-controller/README.zh.md index b88bd7a48e..edebf8bdda 100644 --- a/packages/api/session-controller/README.zh.md +++ b/packages/api/session-controller/README.zh.md @@ -29,13 +29,15 @@ kind: "package-reference" Client journal 在发布 follow 快照、live entry 或历史页之前验证精确的 V3 事件 envelope。它复用浏览器安全的 Session validator,检查必需的 surface marker、精确的 replacement endpoint、更早且唯一的 source seq、内嵌 Assistant 提供方元数据、request header 可选字段的省略规则以及工具错误一致性。无效 record 直接失败,不删除字段或归一化;范围成员与来源存在性仍由 Host 的持久日志检查。 -每个 endpoint 都声明自己的激活策略。列表只读取持久化 header 与 projection cache row,绝不调用逐 Session stat 或打开冷 Session body。当前格式 cache identity 可以提供全部列表 hint;生命周期匹配的 predecessor cache 只能提供版本兼容的 title,作为可能过时的展示事实,绝不能作为权威 fold seed。搜索、附件、历史页、日志跟随、skill 发现和工作区路径打开可以在不激活 Agent 的情况下检查 persistence;`canOpenWorkspacePath()` 无需指定 Session 即可报告原生打开能力。取消要求 live 状态;queue 变更、模型、重命名、prompt 和文件引用操作可以解析或恢复普通 Session。提示词会在解析 Agent 或追加 Session 事件前,拒绝既没有非空白文本也没有附件的 content;queue edit 只接受非空文本 content。prompt 准入从注入的 [`fileUploads`](../../client/file-upload/README.zh.md) Host 服务取得不透明凭证,在把完整有序内容列表交给 `ctx.attachments` 前解析每个属于同一 Agent 的凭证。`requestId` 已进入 queue 或日志时,prompt 重试直接返回原来的接受结果,不会重复插入消息。只有 create 与 fork 会直接创建新 Agent。该服务把同一套感知 preset 的恢复策略和 subagent ownership fence 同时用于自身方法,以及其他 Remote namespace 使用的 Typert Agent 与 Session lookup。Queue 变更只有一个狭窄例外:当前 projection identity 为 continuable 且来自自身非 seed suffix 的在线 child,可以在两个 inbox 目标上使用普通 Edit、Remove 与 QueueDock Steer action。One-shot、缺失、未知、损坏、仅含 seed identity 或冷 child 继续被拒绝,且不会恢复。skill 目录优先使用已有 live Agent,否则使用所记录 preset 的常驻 scope,因此列表查询绝不会启动 Agent。经过鉴权的文件交付路由通过 `workspaceDesktop()` 获取提供服务的 Host 名称和文件管理器行为。`openWorkspacePath({ path, action: "reveal" })` 将文件管理器导航委托给原生适配器;省略 `action` 时按文件类型关联打开,包括 HTML 和 SVG。两种操作都要求当前文件系统将请求的 Host 路径映射到同一个规范进程路径;无法映射的远端路径会在执行原生命令之前被拒绝。 +每个 endpoint 都声明自己的激活策略。列表只读取持久化 header 与 projection cache row,绝不调用逐 Session stat 或打开冷 Session body。当前格式 cache identity 可以提供全部列表 hint;生命周期匹配的 predecessor cache 只能提供版本兼容的 title,作为可能过时的展示事实,绝不能作为权威 fold seed。搜索、附件、历史页、日志跟随、skill 发现和工作区路径打开可以在不激活 Agent 的情况下检查 persistence;`canOpenWorkspacePath()` 无需指定 Session 即可报告原生打开能力。取消要求 live 状态;queue 变更、模型、重命名、prompt 和文件引用操作可以解析或恢复普通 Session。提示词会在解析 Agent 或追加 Session 事件前,拒绝既没有非空白文本也没有附件的 content;queue edit 只接受非空文本 content。prompt 准入从注入的 [`fileUploads`](../../client/file-upload/README.zh.md) Host 服务取得不透明凭证,在把完整有序内容列表交给 `ctx.attachments` 前解析每个属于同一 Agent 的凭证。`requestId` 已进入 queue 或日志时,prompt 重试直接返回原来的接受结果,不会重复插入消息。只有 create 与 fork 会直接创建新 Agent。该服务把同一套感知 preset 的恢复策略和 subagent ownership fence 同时用于自身方法,以及其他 Remote namespace 使用的 Typert Agent 与 Session lookup。Queue 变更只有一个狭窄例外:当前 projection identity 为 continuable 且来自自身非 seed suffix 的在线 child,可以在两个 inbox 目标上使用普通 Edit、Remove 与 QueueDock Steer action。One-shot、缺失、未知、损坏、仅含 seed identity 或冷 child 继续被拒绝,且不会恢复。skill 目录优先使用已有 live Agent,否则使用所记录 preset 的常驻 scope,因此列表查询绝不会启动 Agent。经过鉴权的文件交付路由通过 `workspaceDesktop()` 获取提供服务的 Host 名称和文件管理器行为。`openWorkspacePath({ path, action: "reveal" })` 将文件管理器导航委托给原生适配器;省略 `action` 时按文件类型关联打开,包括 HTML 和 SVG。两种操作都要求当前文件系统将请求的 Host 路径映射到同一个规范进程路径;无法映射的远端路径会在执行原生命令之前被拒绝。 `session.projections` 通过一次 live-preferred Session observation 读取完整基线,不激活 Agent。Session 不存在时返回 null,并可提供任意已注册的 projection key。Client 通过 `projectionsBySession` 暴露共享值和显式读取状态,由领域选择自身的 key。Session 列表摘要携带 `agentAvailable`,通过已有摘要与状态事件更新,与持久化 projection 相互独立。初始读取与实时 projection 帧使用相同的序号排序规则。 Client 列表行和驻留 Session 使用当前 `sessionListMetadata` 投影纠正过期的空白会话提示;最近活动时间取摘要时间戳与投影中最后一次用户提示词时间的较晚值。当 SessionManager 在列表行到达前创建实例时,会使用已保留的该 Session 元数据对账空白状态。因此,即使旧列表响应仍将已有对话标为空白,新会话操作也不会复用已经打开过的对话。 显式 ID 的 `session.create` 会收养活动 Session,或恢复持久化 Session 并持续持有其写锁。写锁争用返回 `session/writer-held`;调用方可以尝试其他空白会话,同时保留其他失败。`session.list` 根据缓存元数据列出持久化空白会话,不打开冷日志正文。 -Client 列表刷新保留未变化的行对象,并在顺序和值均相同时复用条目数组。每行的 `retainedBy` 包含本地引用来源的正计数;Host 元数据刷新不能覆盖它们。缓存成员检查使用每次刷新构建的 ID 集合,因此对账成本随当前列表和保留缓存的规模线性增长。 +Client 列表刷新保留未变化的行对象,并在顺序和值均相同时复用条目数组。每行的 `retainedBy` 包含正数的本地引用来源计数,Host 元数据刷新不能覆盖它们。缓存成员检查使用每次刷新构建的 ID 集合,因此对账成本随当前列表和保留缓存的规模线性增长。 Host 摘要更新会替换运行状态与 Agent 可用性;本地 create/fork 响应只补充已有行缺失的元数据。普通 Session 被移除后,仅在目录仍有子项时保留其投影 store。 + +投影读取独立于其值保留加载与失败状态。重连会取消上一连接的读取,并重新加载已请求的投影;实时成员更新通过 control stream 到达。父 Agent 可用性来自 Host 摘要,在收到对应摘要或成功的列表 baseline 前保持未知。地址查找直接解析投影中的子项,不会选择它们或创建 scope。 Client 适配器提供 `SessionEventStream`,即绑定到一个普通 Session 或 direct subagent address 的 Gateway `RemoteJournalStream`。它在读取首个 page 前打开 follow,只发布连续的 `replace`、`prepend`、`append` 与 `settle-assistant` 变更,并通过 tail page 修复重连或 seq 缺口。向后分页有两个动词:`loadOlder()` 拉一页 50 条消息,而 `loadThrough(seq)`——轮次跳转加载器——按每页 200 条消息循环拉取直到窗口覆盖目标 seq,重复调用会下调共享目标,遇到无进展的页即停止,忙碌状态复用同一个 `loadingOlder` 快照位。Web 适配器显式选择接收无 cursor 的 Assistant frame:每个 opening 携带活跃 attempt 的 `startedAfterSeq`、`nextIndex` 与紧凑 stream,每个 stream member 都成为排在持久 cursor 之间的 Client-only `assistant/live-chunk` 条目。Host 会随该 baseline 捕获 follower 本地到达序号,并抑制该 cut 及之前的 buffered frame;replacement Agent 可以从 revision 一重新开始。活跃 opening 之后到达的持久 `assistant/message` 或 `assistant/attempt` 只有在其 seq 晚于 `startedAfterSeq` 且轮次与步骤匹配时才会保持暂存;匹配的 end type、seq 与 index 会发布一个具名 settlement delta,删除该 attempt 的瞬态 row、加入持久条目,并保留同一步骤中更早的 retry。已知 attempt 的 revision、密集 index 或 settlement 缺口会重新打开 follow;若 controller 错过 start,则忽略 unknown-attempt frame,并正常发布其持久 settlement。Abandoned end 会发布不含持久条目的 settlement delta,使瞬态 row 立即退出。持久缺口修复 page 不携带 Assistant baseline,因此 held notification 会重新打开 follow 一次,以取得配对的 page 与 baseline。每条历史 record 只覆盖自身的事件 seq。业务、persistence 或无法恢复的连续性错误会终止 stream,只有物理载体断开才触发自动恢复。`SessionControlStream` 是 Gateway `RemoteSnapshotStream`;每代都以完整的进程本地 baseline 开始,因此重连会替换 jobs 和 projection 状态,而不会把瞬态值当作 durable event。每次 Host generation 就绪时,同步的 Client 订阅会先清除保留的投影值及其水位,再刷新查询并重新打开 control stream,其中也包括 control baseline 中没有列出的 Session。首次 control stream 会等待 generation 就绪,确保其 opening 值不会先于旧状态清理到达。上一代尚未完成的 list 响应无法重新发布这些值。同一 generation 内,延迟到达的 control baseline 不能覆盖或清除较新的 list、history 或 live 值。持久 `inbox` 投影通过与其他投影相同的冷读取和重连路径传输两份待处理列表。Client Agent 上下文提供独立 [`fileUpload`](../../client/file-upload/README.zh.md) 服务使用的身份;Session 对象提供生命周期、prompt、queue 与历史操作,不提供文件传输。 @@ -44,12 +46,14 @@ Session 对象还承载本地提交回显:`session.beginSubmission` 在调用 面向用户调用的 `skills/list` 元数据包含胜出提供方可选的指令文件 `path`。输入框可据此预览文件,无需加载每个 skill 的正文或激活冷态 Agent。 -分叉复制截至选中已结束轮次的历史,并包含其 `turn/end`。该位置之后的事件均被排除,包括排队输入和模型设置变更。省略锚点或锚点超出日志末尾时,选择最后一个已结束轮次;位于未结束轮次内的锚点会被拒绝。 +Fork 复制 `atSeq` 所选的精确事件前缀,包含切点事件,允许在开放轮次内截取。子会话在合成的 fork 结果和结束事件之前记录继承标记。省略 `atSeq` 时选择最近已结束轮次及其独立尾部,在下一轮次或排队输入之前停止;不存在的事件会被拒绝。聊天操作选择已结束轮次。 恢复会话时若已有写句柄占用,返回 `session/writer-held`,并携带会话 id;其他恢复失败仍返回 `gateway/internal`。 `loadThrough(seq)` 在共享目标被覆盖或加载结束前私下保留较早页面,随后把成功取得的页面按顺序作为一次前插发布。历史加载期间实时事件仍然可见。后续页面失败时保留已成功取得的部分;历史窗口被替换时丢弃被替换窗口的暂存页面。普通 `loadOlder()` 仍直接发布其单页结果。 +队列编辑仅允许用非空文本替换待处理内容。 + ## Client 引用 diff --git a/packages/api/session-controller/src/client/contract/sessions.ts b/packages/api/session-controller/src/client/contract/sessions.ts index 9b51f9066b..8f016ab711 100644 --- a/packages/api/session-controller/src/client/contract/sessions.ts +++ b/packages/api/session-controller/src/client/contract/sessions.ts @@ -91,21 +91,16 @@ export interface ISessions { /** * Resolve an already discovered direct-parent address without opening it. * @param id - possible addressed child id. - * @returns the retained address, when present. + * @returns a retained or loaded-catalog address, without retaining a new selection or scope. */ subagentAddress(id: SessionId): SubagentAddress | undefined + /** - * Mark whether a catalog menu is consuming live membership updates. - * @param parentSessionId - catalog owner. - * @param open - current menu state. - */ - setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void - /** - * Refresh one direct-child catalog. - * @param parentSessionId - catalog owner. + * Load all Session projections once per connection; retry an unsuccessful initial read. + * @param sessionId - Session to inspect without opening its conversation. * @returns completion of the current or newly started refresh. */ - refreshSubagents(parentSessionId: SessionId): Promise + refreshProjections(sessionId: SessionId): Promise /** * Refresh the Host-authoritative Session list. @@ -124,12 +119,13 @@ export interface ISessions { signal: AbortSignal, ): Promise> /** - * Fork a session from a completed-turn prefix of the source; on resolution - * the child is in the catalog and may be explicitly retained. - * @param opts - source session id, the optional event seq anchoring the - * cut (the boundary is the first turn/end at or after it; an in-log - * anchor in an open turn is unavailable rather than clipped backward), - * and whether to increment an inherited durable title before resolving. + * Fork a session from an exact inclusive prefix of the source; on + * resolution the child is catalogued and can be explicitly retained. + * @param opts - source session id, the optional exact inclusive boundary + * seq (a real event seq the caller already knows; a cut inside an open + * turn is balanced Host-side with synthetic closers, and omission selects + * the latest completed-turn prefix), and whether to increment an + * inherited durable title before resolving. * @returns the child session id. * @throws when the fork fails, or when a requested child-title rename fails after creation. */ diff --git a/packages/api/session-controller/src/client/index.ts b/packages/api/session-controller/src/client/index.ts index 03520f5da1..b9600f36a6 100644 --- a/packages/api/session-controller/src/client/index.ts +++ b/packages/api/session-controller/src/client/index.ts @@ -32,7 +32,7 @@ export type { SessionListPhase, SessionListSnapshot, SessionSearchResultItem, - SubagentCatalogSnapshot, + SessionProjectionSnapshot, } from './sessions/manager.ts' export type { Session } from './sessions/session.ts' export type { diff --git a/packages/api/session-controller/src/client/sessions/lineage.ts b/packages/api/session-controller/src/client/sessions/lineage.ts index 496087f6ad..56d06d3e43 100644 --- a/packages/api/session-controller/src/client/sessions/lineage.ts +++ b/packages/api/session-controller/src/client/sessions/lineage.ts @@ -64,8 +64,9 @@ export function flattenLineage( return } visited.add(s.sessionId) + const { agentAvailable: _agentAvailable, ...row } = s out.push({ - ...s, + ...row, depth, }) const kids = children.get(s.sessionId) diff --git a/packages/api/session-controller/src/client/sessions/manager.ts b/packages/api/session-controller/src/client/sessions/manager.ts index c0c0990cf2..b6061ce2b4 100644 --- a/packages/api/session-controller/src/client/sessions/manager.ts +++ b/packages/api/session-controller/src/client/sessions/manager.ts @@ -1,6 +1,6 @@ /** Host catalog, durable projection caches, and explicitly retained Client instances. */ -import type { SubagentAddress, SubagentCatalog } from '@deepseek-ai/dsh-subagent/client' +import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client' import { SessionSeq, type SessionId, type SessionSeqCursor } from '@deepseek-ai/dsh-session/types' import type { SessionProjectionMap } from '@deepseek-ai/dsh-session-projection/types' import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types' @@ -52,37 +52,29 @@ export interface SessionListSnapshot { /** Arrival lifecycle (see {@link SessionListPhase}); `state` stays the pull-activity axis. */ phase: SessionListPhase error: RemoteFailure | null - subagentsByParent: Readonly> + projectionsBySession: Readonly> /** Background jobs per session; an absent key is an empty set. */ jobsBySession: Readonly> } -/** One parent-addressed durable catalog projected through the sessions snapshot. */ -export type SubagentCatalogSnapshot = Omit & { - /** Absent until the first successful catalog read. */ - readonly parentAvailable?: boolean - state: 'loading' | 'ready' | 'error' - error: RemoteFailure | null +/** Shared projection values and the lifecycle of their explicit baseline read. */ +export interface SessionProjectionSnapshot { + readonly values: Readonly> + readonly state: 'idle' | 'loading' | 'ready' | 'error' + readonly error: RemoteFailure | null } -function catalogAvailability(parentAvailable: boolean | undefined): { - readonly parentAvailable?: boolean -} { - return parentAvailable === undefined ? {} : { parentAvailable } -} - -interface CatalogInflight { +interface ProjectionInflight { readonly promise: Promise - readonly expandableRows: Set - readonly activityRows: Map - /** Removal-time invalidation replayed over the response this request predates. */ - parentAvailableOverride: false | undefined + readonly controller: AbortController } +type ProjectionLoad = Omit + type SessionListMutation = - | { kind: 'upsert'; summary: SessionSummary } + | { kind: 'upsert' | 'placeholder'; summary: SessionSummary } | { kind: 'remove'; sessionId: SessionId } - | { kind: 'status'; sessionId: SessionId; running: boolean } + | { kind: 'status'; sessionId: SessionId; running: boolean; agentAvailable: boolean } | { kind: 'activity'; sessionId: SessionId; updatedAt: number } /** Local first-send flip: the sender clears blank without waiting for a host frame. */ | { kind: 'engaged'; sessionId: SessionId } @@ -106,12 +98,8 @@ export class SessionManager { /** Active list request's mutation log; its identity also fences completion after reconnect. */ private listMutations: SessionListMutation[] | null = null private readonly addresses = new Map() - private readonly catalogs = new Map() - private readonly catalogInflight = new Map() - /** Catalog owners whose membership changed while a pull was in flight: one trailing refresh after it settles. */ - private readonly catalogStale = new Set() - private readonly openCatalogs = new Set() - private readonly catalogDebounce = new Map>() + private readonly projectionLoads = new Map() + private readonly projectionInflight = new Map() /** * Background jobs per session, last-wins from Session Controller's control * stream. An empty set is stored as an absent key, so absence and `[]` are @@ -141,7 +129,7 @@ export class SessionManager { */ resolveTarget(target: SessionTarget): SessionId { const id = typeof target === 'string' ? target : target.childSessionId - const address = typeof target === 'string' ? this.navigationAddress(id) : target + const address = typeof target === 'string' ? this.subagentAddress(id) : target if (typeof target === 'string' && !this.sessions.has(id) && !this.summaries.some(summary => summary.sessionId === id) @@ -151,32 +139,30 @@ export class SessionManager { if (address !== undefined) this.addresses.set(id, address) this.sessions.get(id)?.configureSubagent( address, - address === undefined ? undefined : this.catalogs.get(address.parentSessionId)?.parentAvailable, + address === undefined + ? undefined + : this.agentAvailable(address.parentSessionId), ) return id } - /** - * Return the durable catalog address retained for one child. - * @param sessionId - possible addressed child id. - * @returns The direct-parent address, when navigation discovered one. - */ - subagentAddress(sessionId: SessionId): SubagentAddress | undefined { - return this.navigationAddress(sessionId) - } - /** * Resolve an address for breadcrumb navigation without retaining transport authority. * @param sessionId - possible child id in an already-loaded catalog. * @returns A retained or catalog-derived direct-parent address. */ - navigationAddress(sessionId: SessionId): SubagentAddress | undefined { + subagentAddress(sessionId: SessionId): SubagentAddress | undefined { const retained = this.addresses.get(sessionId) if (retained !== undefined) return retained - for (const [parentSessionId, catalog] of this.catalogs) { - const child = catalog.entries.find(entry => entry.kind === 'child' && entry.id === sessionId) - if (child?.kind === 'child') { - return { parentSessionId, childSessionId: sessionId, mode: child.mode } + for (const parentSessionId of this.projectionStores.keys()) { + const child = this.projectionStores.get(parentSessionId)?.values().subagentCatalog + ?.find(entry => entry.id === sessionId) + if (child !== undefined) { + return { + parentSessionId, + childSessionId: sessionId, + mode: child.mode, + } } } return undefined @@ -203,10 +189,10 @@ export class SessionManager { * @returns once catalog requests and every Session stream have stopped. */ async dispose(): Promise { - for (const timer of this.catalogDebounce.values()) clearTimeout(timer) - this.catalogDebounce.clear() - this.catalogStale.clear() - this.openCatalogs.clear() + const reads = [...this.projectionInflight.values()] + for (const { controller } of reads) controller.abort() + this.projectionInflight.clear() + await Promise.all(reads.map(read => read.promise)) const sessions = [...this.sessions.values()] this.sessions.clear() this.addresses.clear() @@ -250,13 +236,13 @@ export class SessionManager { session.handleRunning(summary.running) } else { const address = this.addresses.get(sessionId) - const child = address === undefined ? undefined : this.catalogs.get(address.parentSessionId)?.entries - .find(entry => entry.kind === 'child' && entry.id === sessionId) - if (child?.kind === 'child') { + const child = address === undefined ? undefined : this.projectionStores.get(address.parentSessionId)?.values().subagentCatalog + ?.find(entry => entry.id === sessionId) + if (child !== undefined) { // A catalogued child exists only after its delegated session has // durable history, even though child rows do not carry `blank`. session.handleBlank(false) - session.handleRunning(child.activity === 'running') + session.handleRunning(false) } else { // Retained metadata may have notified before this Session existed. session.handleBlank(true) @@ -270,11 +256,11 @@ export class SessionManager { const address = this.addresses.get(sessionId) const parentAvailable = address === undefined ? undefined - : this.catalogs.get(address.parentSessionId)?.parentAvailable + : this.agentAvailable(address.parentSessionId) return new Session(sessionId, this.remote, { ...(address === undefined ? {} : { address, - ...catalogAvailability(parentAvailable), + ...parentAvailable === undefined ? {} : { parentAvailable }, }), // The sender's local first-send flip mirrors into the list row so the // session surfaces (lists filter on blank) before any host frame lands. @@ -304,101 +290,58 @@ export class SessionManager { } /** - * Refresh one direct-child catalog, reusing its in-flight request. - * @param parentSessionId - catalog owner. + * Load a complete projection baseline once per connection; retry unsuccessful reads. + * @param sessionId - Session to inspect without opening its conversation. + * @returns completion of the current or newly started read. */ - refreshSubagents(parentSessionId: SessionId): Promise { - const existing = this.catalogInflight.get(parentSessionId) + refreshProjections(sessionId: SessionId): Promise { + const existing = this.projectionInflight.get(sessionId) if (existing !== undefined) return existing.promise - const previous = this.catalogs.get(parentSessionId) - const expandableRows = new Set() - const activityRows = new Map() - this.catalogs.set(parentSessionId, { - entries: previous?.entries ?? [], - ...(previous?.parentAvailable === undefined - ? {} - : { parentAvailable: previous.parentAvailable }), - state: 'loading', - error: null, - }) + if (this.projectionLoads.get(sessionId)?.state === 'ready') return Promise.resolve() + const controller = new AbortController() + const store = this.projectionStore(sessionId) + const initialValues = store.values() + this.projectionLoads.set(sessionId, { state: 'loading', error: null }) this.notifier.markDirty() const operation = (async () => { try { - const result = await this.remote.subagents.list(parentSessionId) + const result = await this.remote.session.projections({ sessionId }, controller.signal) + if (controller.signal.aborted) return if (result.ok) { - const parentAvailable = this.catalogInflight.get(parentSessionId)?.parentAvailableOverride - ?? result.value.parentAvailable - this.catalogs.set(parentSessionId, { - ...result.value, - entries: this.withCatalogMutations(result.value.entries, expandableRows, activityRows), - parentAvailable, - state: 'ready', - error: null, - }) - for (const [childId, address] of this.addresses) { - if (address.parentSessionId !== parentSessionId) continue - this.sessions.get(childId)?.handleSubagentParentAvailable(parentAvailable) + if (result.value !== null) { + store.seed({ ...result.value, asOfSeq: sessionSeqCursor(result.value.asOfSeq) }) + } else if (store.values() === initialValues) { + // A later frame proves existence independently of an earlier missing read. + store.clear() } + this.projectionLoads.set(sessionId, { state: 'ready', error: null }) } else { - this.catalogs.set(parentSessionId, { - entries: this.withCatalogMutations( - previous?.entries ?? [], expandableRows, activityRows, - ), - ...catalogAvailability( - this.catalogInflight.get(parentSessionId)?.parentAvailableOverride - ?? previous?.parentAvailable, - ), - state: 'error', - error: result.error, - }) + this.projectionLoads.set(sessionId, { state: 'error', error: result.error }) } } catch (error: unknown) { + if (controller.signal.aborted) return if (!isRemoteFailure(error)) throw error - this.catalogs.set(parentSessionId, { - entries: this.withCatalogMutations( - previous?.entries ?? [], expandableRows, activityRows, - ), - ...catalogAvailability( - this.catalogInflight.get(parentSessionId)?.parentAvailableOverride - ?? previous?.parentAvailable, - ), - state: 'error', - error, - }) + this.projectionLoads.set(sessionId, { state: 'error', error }) } finally { - this.catalogInflight.delete(parentSessionId) - // Re-arm the trailing pull before the dirty notify: the response the - // caller observed predates the stale-marking change, so the follow-up - // refresh is the only carrier of that change. - if (this.catalogStale.delete(parentSessionId)) void this.refreshSubagents(parentSessionId) - this.notifier.markDirty() + if (!controller.signal.aborted) { + this.projectionInflight.delete(sessionId) + this.notifier.markDirty() + } } })() - this.catalogInflight.set(parentSessionId, { - promise: operation, - expandableRows, - activityRows, - parentAvailableOverride: undefined, - }) + this.projectionInflight.set(sessionId, { promise: operation, controller }) return operation } - /** - * Mark whether a catalog menu is consuming live membership updates. - * @param parentSessionId - catalog owner. - * @param open - current menu state. - */ - setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void { - if (open) { - this.openCatalogs.add(parentSessionId) - void this.refreshSubagents(parentSessionId) - } else { - this.openCatalogs.delete(parentSessionId) - const timer = this.catalogDebounce.get(parentSessionId) - if (timer !== undefined) { - clearTimeout(timer) - this.catalogDebounce.delete(parentSessionId) - } + private agentAvailable(sessionId: SessionId): boolean | undefined { + return this.summaries.find(summary => summary.sessionId === sessionId)?.agentAvailable + ?? (this.listPhase === 'ready' ? false : undefined) + } + + private updateParentAvailability(): void { + for (const [childId, address] of this.addresses) { + const available = this.agentAvailable(address.parentSessionId) + if (available !== undefined) this.sessions.get(childId)?.handleSubagentParentAvailable(available) } } @@ -424,6 +367,7 @@ export class SessionManager { this.summaries = mutations.reduce(applyMutation, baseline) this.listState = 'idle' this.listPhase = 'ready' + this.updateParentAvailability() // Sessions reconcile list blank hints with their current metadata projection. for (const s of this.summaries) { const session = this.sessions.get(s.sessionId) @@ -506,7 +450,7 @@ export class SessionManager { : { ...(opts.cwd === undefined ? {} : { cwd: opts.cwd }), ...shared } const result = await this.remote.session.create(payload) if (result.ok) { - this.recordMutation({ kind: 'upsert', summary: { + this.recordMutation({ kind: 'placeholder', summary: { agentAvailable: true, sessionId: result.value.sessionId, updatedAt: Date.now(), running: false, blank: true, ...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}), } }) @@ -516,7 +460,7 @@ export class SessionManager { // so expose it immediately as Ungrouped while the caller keeps the // prompt buffer and decides whether to retry attachment. if (publishedSessionId !== undefined) { - this.recordMutation({ kind: 'upsert', summary: { + this.recordMutation({ kind: 'placeholder', summary: { agentAvailable: true, sessionId: publishedSessionId, updatedAt: Date.now(), running: false, @@ -529,11 +473,12 @@ export class SessionManager { /** * Contract session.fork; on success merge the child into summaries - * immediately (same synchronous-addressability guarantee as create). The - * child carries the source's history, so it is never blank; lineage rides - * parentSessionId so the list nests it under its source. A child published - * before Workspace attachment fails is also reconciled into the list. - * @param opts - source session and the optional seq anchoring the cut. + * immediately (same synchronous-addressability guarantee as create). + * Blankness starts provisionally true so the authoritative Host summary can + * preserve it or lower it after an exact cut before the first `turn/start`; + * lineage rides parentSessionId. A child published before Workspace + * attachment fails is also reconciled into the list. + * @param opts - source session and the optional exact inclusive boundary seq. * @returns the fork result (the child session id). */ async fork( @@ -548,8 +493,8 @@ export class SessionManager { ? result.value.sessionId : workspaceAttachSessionId(result.error) if (childId !== undefined) { - this.recordMutation({ kind: 'upsert', summary: { - sessionId: childId, updatedAt: Date.now(), running: false, blank: false, + this.recordMutation({ kind: 'placeholder', summary: { agentAvailable: true, + sessionId: childId, updatedAt: Date.now(), running: false, blank: true, parentSessionId: opts.sessionId, ...(source?.cwd !== undefined ? { cwd: source.cwd } : {}), } }) @@ -558,13 +503,12 @@ export class SessionManager { } /** - * Insert-or-enrich a locally synthesized summary: a new id prepends; an - * existing entry only gains fields it lacks (the session-added frame and the - * create() echo race — whichever lands second must fill the placeholder's - * missing cwd/parentSessionId, never overwrite list-refresh data). + * Merge a Host summary, replacing live state and filling missing metadata. + * Local create/fork placeholders only fill metadata on an existing row. */ private mergeSummary(summary: SessionSummary): void { this.recordMutation({ kind: 'upsert', summary }) + this.updateParentAvailability() } /** Apply immediately and retain for replay when a list response is in flight. */ @@ -652,13 +596,6 @@ export class SessionManager { store.apply(key, value, sessionSeqCursor(projections.asOfSeq)) } } - if (summary.origin === 'subagent' && summary.parentSessionId !== undefined) { - this.markCatalogParentExpandable(summary.parentSessionId) - } - if (summary.parentSessionId !== undefined - && this.openCatalogs.has(summary.parentSessionId)) { - this.scheduleCatalogRefresh(summary.parentSessionId) - } } /** @@ -666,25 +603,21 @@ export class SessionManager { * @param sessionId - removed Session identity. */ handleSessionRemoved(sessionId: SessionId): void { - const summary = this.summaries.find(candidate => candidate.sessionId === sessionId) - const durableSubagent = summary?.origin === 'subagent' || this.addresses.has(sessionId) + const durableSubagent = this.subagentAddress(sessionId) !== undefined + || this.summaries.some(summary => summary.sessionId === sessionId && summary.origin === 'subagent') this.recordMutation(durableSubagent - ? { kind: 'status', sessionId, running: false } + ? { kind: 'status', sessionId, running: false, agentAvailable: false } : { kind: 'remove', sessionId }) - this.updateCatalogActivity(sessionId, false) if (durableSubagent) this.sessions.get(sessionId)?.handleRunning(false) else this.sessions.get(sessionId)?.handleRemoved() this.jobsBySession.delete(sessionId) - if (!durableSubagent) this.projectionStores.delete(sessionId) - const inflightCatalog = this.catalogInflight.get(sessionId) - if (inflightCatalog !== undefined) { - inflightCatalog.parentAvailableOverride = false - this.catalogStale.add(sessionId) - } - const ownedCatalog = this.catalogs.get(sessionId) - if (ownedCatalog !== undefined && ownedCatalog.parentAvailable) { - this.catalogs.set(sessionId, { ...ownedCatalog, parentAvailable: false }) + const catalog = this.projectionStores.get(sessionId)?.values().subagentCatalog + if (!durableSubagent && (catalog === undefined || catalog.length === 0)) { + this.projectionStores.delete(sessionId) } + this.projectionInflight.get(sessionId)?.controller.abort() + this.projectionInflight.delete(sessionId) + this.projectionLoads.delete(sessionId) for (const [childId, address] of this.addresses) { if (address.parentSessionId === sessionId) { this.sessions.get(childId)?.handleSubagentParentAvailable(false) @@ -698,9 +631,9 @@ export class SessionManager { * @param running - current Agent running state. */ handleSessionStatus(sessionId: SessionId, running: boolean): void { - this.recordMutation({ kind: 'status', sessionId, running }) + this.recordMutation({ kind: 'status', sessionId, running, agentAvailable: true }) + this.updateParentAvailability() this.sessions.get(sessionId)?.handleRunning(running) - this.updateCatalogActivity(sessionId, running) } /** @@ -732,89 +665,15 @@ export class SessionManager { this.listMutations = null this.listInflight = null void this.refreshList() - const parents = new Set(this.openCatalogs) + const parents = new Set(this.projectionLoads.keys()) for (const id of this.sessions.keys()) { const address = this.addresses.get(id) if (address !== undefined) parents.add(address.parentSessionId) } - for (const parentSessionId of parents) void this.refreshSubagents(parentSessionId) - } - - /** Debounce membership refetches for an explicitly consumed catalog. */ - private scheduleCatalogRefresh(parentSessionId: SessionId): void { - if (this.catalogDebounce.has(parentSessionId)) return - const timer = setTimeout(() => { - this.catalogDebounce.delete(parentSessionId) - // The in-flight response predates the membership frame that scheduled - // this callback. Queue one post-settlement pull instead of treating an - // ordinary overlapping read as evidence that catalog membership changed. - if (this.catalogInflight.has(parentSessionId)) { - this.catalogStale.add(parentSessionId) - return - } - void this.refreshSubagents(parentSessionId) - }, 50) - this.catalogDebounce.set(parentSessionId, timer) - } - - /** Apply one Agent-driver transition to loaded and in-flight catalogs. */ - private updateCatalogActivity(childSessionId: SessionId, running: boolean): void { - const activity = running ? 'running' as const : 'inactive' as const - for (const inflight of this.catalogInflight.values()) { - inflight.activityRows.set(childSessionId, activity) - } - let changed = false - for (const [parentSessionId, catalog] of this.catalogs) { - if (!catalog.entries.some(entry => - entry.kind === 'child' && entry.id === childSessionId && entry.activity !== activity)) continue - const entries = catalog.entries.map((entry) => { - if (entry.kind !== 'child' || entry.id !== childSessionId) return entry - return { ...entry, activity } - }) - changed = true - this.catalogs.set(parentSessionId, { ...catalog, entries }) - } - if (changed) this.notifier.markDirty() - } - - /** Preserve and project a positive expandability hint after one direct subagent publishes. */ - private markCatalogParentExpandable(parentSessionId: SessionId): void { - this.applyCatalogParentExpandable(parentSessionId) - for (const inflight of this.catalogInflight.values()) inflight.expandableRows.add(parentSessionId) - } - - /** Apply one positive expandability hint to every loaded catalog containing that unique row id. */ - private applyCatalogParentExpandable(parentSessionId: SessionId): void { - let changed = false - for (const [catalogParentId, catalog] of this.catalogs) { - if (!catalog.entries.some(entry => - entry.kind === 'child' && entry.id === parentSessionId && !entry.hasChildren)) continue - const entries = catalog.entries.map((entry) => { - if (entry.kind !== 'child' || entry.id !== parentSessionId || entry.hasChildren) return entry - return { ...entry, hasChildren: true } - }) - changed = true - this.catalogs.set(catalogParentId, { ...catalog, entries }) - } - if (changed) this.notifier.markDirty() - } - - /** Fold request-local row mutations into one catalog result before publication. */ - private withCatalogMutations( - entries: SubagentCatalog['entries'], - expandableRows: ReadonlySet, - activityRows: ReadonlyMap, - ): SubagentCatalog['entries'] { - return entries.map((entry) => { - if (entry.kind !== 'child') return entry - const activity = activityRows.get(entry.id) - if (!expandableRows.has(entry.id) && activity === undefined) return entry - return { - ...entry, - ...expandableRows.has(entry.id) ? { hasChildren: true } : {}, - ...activity === undefined ? {} : { activity }, - } - }) + for (const { controller } of this.projectionInflight.values()) controller.abort() + this.projectionInflight.clear() + this.projectionLoads.clear() + for (const parentSessionId of parents) void this.refreshProjections(parentSessionId) } private buildListSnapshot(): SessionListSnapshot { @@ -858,7 +717,10 @@ export class SessionManager { state: this.listState, phase: this.listPhase, error: this.listError, - subagentsByParent: Object.fromEntries(this.catalogs), + projectionsBySession: Object.fromEntries([...this.projectionStores].map(([sessionId, store]) => [ + sessionId, + { values: store.values(), state: 'idle', error: null, ...this.projectionLoads.get(sessionId) }, + ])), jobsBySession: Object.fromEntries(this.jobsBySession), } } @@ -867,7 +729,8 @@ export class SessionManager { /** Apply one list mutation without deriving display order. */ function applyMutation(summaries: readonly SessionSummary[], mutation: SessionListMutation): SessionSummary[] { switch (mutation.kind) { - case 'upsert': { + case 'upsert': + case 'placeholder': { const existing = summaries.find(summary => summary.sessionId === mutation.summary.sessionId) if (existing === undefined) return [mutation.summary, ...summaries] const filled: SessionSummary = { @@ -875,6 +738,10 @@ function applyMutation(summaries: readonly SessionSummary[], mutation: SessionLi // Blank only lowers: a stale true (session-added racing the local // first send) never re-hides an already-surfaced session. blank: existing.blank && mutation.summary.blank, + ...(mutation.kind === 'upsert' ? { + agentAvailable: mutation.summary.agentAvailable, + running: mutation.summary.running, + } : {}), ...(existing.cwd === undefined && mutation.summary.cwd !== undefined ? { cwd: mutation.summary.cwd } : {}), ...(existing.parentSessionId === undefined && mutation.summary.parentSessionId !== undefined ? { parentSessionId: mutation.summary.parentSessionId } : {}), @@ -883,6 +750,7 @@ function applyMutation(summaries: readonly SessionSummary[], mutation: SessionLi } if (filled.cwd === existing.cwd && filled.parentSessionId === existing.parentSessionId && filled.origin === existing.origin && filled.blank === existing.blank + && filled.agentAvailable === existing.agentAvailable && filled.running === existing.running ) return [...summaries] return summaries.map(summary => summary.sessionId === mutation.summary.sessionId ? filled : summary) } @@ -892,8 +760,9 @@ function applyMutation(summaries: readonly SessionSummary[], mutation: SessionLi // running:true doubles as the cross-client blank flip (a blank session // never runs, so the first running frame proves a message landed). return summaries.map(summary => summary.sessionId === mutation.sessionId - && (summary.running !== mutation.running || (mutation.running && summary.blank)) - ? { ...summary, running: mutation.running, blank: summary.blank && !mutation.running } + && (summary.running !== mutation.running + || summary.agentAvailable !== mutation.agentAvailable || (mutation.running && summary.blank)) + ? { ...summary, running: mutation.running, agentAvailable: mutation.agentAvailable, blank: summary.blank && !mutation.running } : summary) case 'activity': return summaries.map(summary => summary.sessionId === mutation.sessionId diff --git a/packages/api/session-controller/src/client/sessions/remotes.ts b/packages/api/session-controller/src/client/sessions/remotes.ts index c2e585514b..8e084384d4 100644 --- a/packages/api/session-controller/src/client/sessions/remotes.ts +++ b/packages/api/session-controller/src/client/sessions/remotes.ts @@ -9,7 +9,7 @@ import type { ClientRemote } from '@deepseek-ai/dsh-api-gateway/client' import type { CommandSubmitAttachment } from '@deepseek-ai/dsh-commands/types' import type { SessionId } from '@deepseek-ai/dsh-session/types' import type { - SubagentCatalog, SubagentInterruptReceipt, SubagentPromptReceipt, SubagentPromptRequest, + SubagentInterruptReceipt, SubagentPromptReceipt, SubagentPromptRequest, } from '@deepseek-ai/dsh-subagent/client' import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol' import type { SessionRemote } from '../transport.ts' @@ -26,7 +26,6 @@ export interface SessionCommandsRemote { /** Narrow subagent namespace consumed by a Client Session and its manager. */ export interface SessionSubagentsRemote { - list(parentSessionId: SessionId, signal?: AbortSignal): Promise> prompt( request: SubagentPromptRequest, signal?: AbortSignal, diff --git a/packages/api/session-controller/src/client/sessions/service.ts b/packages/api/session-controller/src/client/sessions/service.ts index 1c7196a272..a44c4147d9 100644 --- a/packages/api/session-controller/src/client/sessions/service.ts +++ b/packages/api/session-controller/src/client/sessions/service.ts @@ -20,7 +20,7 @@ import type { SessionReferenceSource } from '../index.ts' import { createScope, scopeIdentityOf, scopeOf as scopeTagOf } from '../scope.ts' import { SessionManager } from './manager.ts' import type { SessionRemotes } from './remotes.ts' -import type { SessionListPhase, SessionSearchResultItem, SubagentCatalogSnapshot } from './manager.ts' +import type { SessionListPhase, SessionSearchResultItem, SessionProjectionSnapshot } from './manager.ts' import type { Session } from './session.ts' /** Session list row projected from the host list RPC plus live stream increments. */ @@ -34,6 +34,7 @@ export interface SessionSummary { parentId?: SessionId /** Coarse durable origin for navigation filtering; not a continuation capability. */ origin?: 'subagent' + /** Host running state for `ids` members; a display fallback for other rows. */ running: boolean /** Local ownership counts; Host metadata refreshes cannot overwrite them. */ readonly retainedBy: SessionRetainInfo['retainedBy'] @@ -51,14 +52,14 @@ export interface SessionSummary { /** Catalog metadata and local source counts; catalog membership owns no Client generation. */ export interface SessionListState { - /** Host-list order; addressed breadcrumb-only rows are excluded. */ + /** Host list order; every id has a matching byId row in the same snapshot. */ ids: SessionId[] /** Host/catalog rows plus local fallback rows for live Client generations; only `ids` expresses Host-list membership. */ byId: Record /** Arrival lifecycle projected 1:1 from the manager snapshot (see SessionListPhase): empty-with-ready means "truly no sessions". */ phase: SessionListPhase - /** Direct durable catalogs keyed by their selected parent address. */ - subagentsByParent: Readonly> + /** Shared projection values and explicit-read state, including unopened Sessions. */ + projectionsBySession: Readonly> /** * Background jobs each session can see, mirrored last-wins from Session * Controller's control baseline and `jobs` frames. A missing key is an empty @@ -261,7 +262,7 @@ export class ClientSessions implements ISessions { ) { this.manager = new SessionManager(remote) this.list = createSnapshotStore({ - ids: [], byId: {}, phase: 'pending', subagentsByParent: {}, jobsBySession: {}, + ids: [], byId: {}, phase: 'pending', projectionsBySession: {}, jobsBySession: {}, }) const disposeManagerProjection = this.manager.subscribe(() => { this.projectList() }) rootCtx.effect(() => async () => { @@ -337,27 +338,18 @@ export class ClientSessions implements ISessions { * Resolve an already discovered direct-parent address without opening it. * Feature plugins use this to avoid Agent-bound RPCs in persisted child views. * @param id - possible addressed child id. - * @returns The retained address, when present. + * @returns A retained or loaded-catalog address, without retaining a new selection or scope. */ subagentAddress(id: SessionId): SubagentAddress | undefined { return this.manager.subagentAddress(id) } /** - * Inform the Session Controller whether a catalog menu is consuming membership updates. - * @param parentSessionId - selected parent. - * @param open - menu state. + * Load all Session projections once per connection; retry an unsuccessful initial read. + * @param sessionId - Session to inspect without opening its conversation. */ - setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void { - this.manager.setSubagentCatalogOpen(parentSessionId, open) - } - - /** - * Refresh one direct-child catalog. - * @param parentSessionId - catalog owner. - */ - refreshSubagents(parentSessionId: SessionId): Promise { - return this.manager.refreshSubagents(parentSessionId) + refreshProjections(sessionId: SessionId): Promise { + return this.manager.refreshProjections(sessionId) } /** @@ -450,15 +442,14 @@ export class ClientSessions implements ISessions { } /** - * Fork a Session from a completed-turn prefix of the source and publish - * the child in the catalog before resolving. - * @param opts - source session id, the optional event seq anchoring the - * cut (the boundary is the first turn/end at or after it; an in-log - * anchor in an open turn is unavailable rather than clipped backward), - * and whether to increment an inherited durable title before resolving. - * A fractional anchor floors to a real event seq: the frozen nodes of an - * interrupted turn carry flow-ordering seqs between two events, and the - * wire takes integers only. + * Fork a session from an exact inclusive prefix of the source (same + * synchronous-addressability guarantee as {@link ClientSessions.create}: + * on resolution the child is catalogued and may be explicitly retained). + * @param opts - source session id, the optional exact inclusive boundary + * seq (a real event seq the caller already knows; a cut inside an open + * turn is balanced Host-side with synthetic closers, and omission selects + * the latest completed-turn prefix), and whether to increment an + * inherited durable title before resolving. * @returns the child session id. * @throws {SessionForkError} with the source id. * @throws {Error} when a requested child-title rename fails after creation. @@ -473,10 +464,7 @@ export class ClientSessions implements ISessions { : undefined const result = await this.manager.fork({ sessionId: opts.sessionId, - // Flooring lands inside the anchor's own turn (every turn opens with a - // turn/start), so the host's first-turn/end-at-or-after cut still ends - // on that turn — never clipped back to the previous one. - ...(opts.atSeq === undefined ? {} : { atSeq: SessionSeq(Math.floor(opts.atSeq)) }), + ...(opts.atSeq === undefined ? {} : { atSeq: SessionSeq(opts.atSeq) }), }) if (!result.ok) throw new SessionForkError(result.error, opts.sessionId) this.projectList() @@ -629,7 +617,7 @@ export class ClientSessions implements ISessions { private projectList(): void { const previousById = this.list.getSnapshot().byId const { - items, phase, subagentsByParent, jobsBySession, + items, phase, projectionsBySession, jobsBySession, } = this.manager.getListSnapshot() const ids: SessionId[] = [] const byId: Record = {} @@ -651,9 +639,8 @@ export class ClientSessions implements ISessions { ...(entry.origin !== undefined ? { origin: entry.origin } : {}), } } - for (const [parentId, catalog] of Object.entries(subagentsByParent)) { - for (const child of catalog.entries) { - if (child.kind !== 'child') continue + for (const [parentId, projection] of Object.entries(projectionsBySession)) { + for (const child of projection.values.subagentCatalog ?? []) { const childId = child.id const summary = byId[childId] const projectionValues = summary?.projectionValues ?? this.manager.projectionValues(childId) @@ -663,7 +650,7 @@ export class ClientSessions implements ISessions { if (summary === undefined) { byId[childId] = { id: childId, displayTitle, parentId: parentId as SessionId, - origin: 'subagent', running: child.activity === 'running', blank: false, updatedAt: 0, + origin: 'subagent', running: this.scopes.get(childId)?.session.getSnapshot().running ?? false, blank: false, updatedAt: 0, retainedBy: this.retentionSnapshot(childId).retainedBy, ...(projectionValues === undefined ? {} : { projectionValues }), ...(title === undefined ? {} : { title }), @@ -690,7 +677,7 @@ export class ClientSessions implements ISessions { ...(address === undefined ? {} : { parentId: address.parentSessionId, origin: 'subagent' }), } } - this.list.set({ ids, byId, phase, subagentsByParent, jobsBySession }) + this.list.set({ ids, byId, phase, projectionsBySession, jobsBySession }) } private startScopeDrop( diff --git a/packages/api/session-controller/src/client/sessions/session.ts b/packages/api/session-controller/src/client/sessions/session.ts index 67c7b2f164..cd38a26fcf 100644 --- a/packages/api/session-controller/src/client/sessions/session.ts +++ b/packages/api/session-controller/src/client/sessions/session.ts @@ -63,7 +63,7 @@ interface PendingHistory { export interface SessionOptions { /** Catalog-discovered address selecting non-activating subagent transport. */ address?: SubagentAddress - /** Whether the exact direct parent Agent was live at the latest catalog read; absent before that read. */ + /** Whether the exact direct parent Agent is available in Host summaries; absent until known. */ parentAvailable?: boolean /** * First ACCEPTED prompt on a blank session (fires at most once, on the diff --git a/packages/api/session-controller/src/commands.ts b/packages/api/session-controller/src/commands.ts index 6003149581..fa456772de 100644 --- a/packages/api/session-controller/src/commands.ts +++ b/packages/api/session-controller/src/commands.ts @@ -14,6 +14,7 @@ import { ReasoningEffortId, assistantStreamChunks, createUserMessage, freezeMessage, } from '@deepseek-ai/dsh-llm' import type { MessageSource } from '@deepseek-ai/dsh-llm' +import { buildForkSeed } from '@deepseek-ai/dsh-session/fork' import { SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionHeader, SessionId, UserMessage } from '@deepseek-ai/dsh-session' import { SessionQueryError, type SessionObservation } from '@deepseek-ai/dsh-session-query' @@ -66,6 +67,22 @@ function hasPromptContent(content: readonly PromptContentCandidate[]): boolean { return content.some(part => part.type !== 'text' || part.text.trim().length > 0) } +/** + * Resolve the omitted-`atSeq` default to the latest completed-turn prefix, + * including standalone events before the next turn begins. + */ +function latestCompletedPrefixBoundary(events: readonly SessionEvent[]): SessionSeq | undefined { + const lastTurnEnd = events.findLast(event => event.type === 'turn/end') + if (lastTurnEnd === undefined) return undefined + let boundary = lastTurnEnd.seq + for (const next of events.slice(boundary + 1)) { + if (next.type === 'turn/start' || (next.type === 'user/message' && next.surfaceOp === 'append') + || next.type === 'agent/inbox/spliced') break + boundary = next.seq + } + return boundary +} + /** Implements Session business commands delegated by the Session Controller Remote service. */ export class SessionCommandController { /** @@ -195,8 +212,10 @@ export class SessionCommandController { } /** - * Create a new ordinary Session from one completed-turn prefix. - * @param request - source Session and optional event anchor. + * Create a new ordinary Session from an exact event prefix. An explicit + * `atSeq` is the inclusive cut; an omitted value selects the latest + * completed-turn prefix. An open cut receives synthetic fork closers. + * @param request - source Session and optional exact event boundary. * @returns the new Session identity. */ async fork(request: SessionForkRequest): Promise { @@ -223,24 +242,17 @@ export class SessionCommandController { ) } using source = observed - const lastSeq = source.events.at(-1)?.seq ?? -1 - const anchoredBoundary = atSeq === undefined - ? undefined - : source.events.find(event => event.type === 'turn/end' && event.seq >= atSeq) - const boundary = anchoredBoundary - ?? (atSeq === undefined || atSeq > lastSeq - ? source.events.findLast(event => event.type === 'turn/end') - : undefined) - if (boundary === undefined) { + const boundary = atSeq ?? latestCompletedPrefixBoundary(source.events) + if (boundary === undefined || source.events[boundary]?.seq !== boundary) { throw new RemoteError( 'session/fork-unavailable', - atSeq !== undefined && atSeq <= lastSeq - ? `session "${request.sessionId}" has not completed the turn containing event ${String(atSeq)}` - : `session "${request.sessionId}" has no completed turn to fork from`, + request.atSeq === undefined + ? `session "${request.sessionId}" has no completed turn to fork from` + : `event ${String(request.atSeq)} does not exist in session "${request.sessionId}" (last seq: ${String(source.events.at(-1)?.seq ?? 'none')})`, { sessionId: request.sessionId }, ) } - const cut = SessionLogOffset(boundary.seq + 1) + const seed = buildForkSeed(source.events, boundary) let workspace: Workspace | undefined try { workspace = await this.forkWorkspace(source.header) @@ -257,8 +269,8 @@ export class SessionCommandController { const { provider, model } = this.ctx.agentDefaultModel.currentSelection() await this.ctx.agents.create({ sessionId: childId, - seed: source.events.slice(0, cut), - inheritedEventCount: cut, + seed, + inheritedEventCount: SessionLogOffset(boundary + 1), meta: { ...(source.header.cwd === undefined ? {} : { cwd: source.header.cwd }), parentSession: source.header.id, @@ -420,6 +432,7 @@ export class SessionCommandController { */ async updateQueue(request: SessionUpdateQueueRequest): Promise { if (request.action.kind === 'edit') { + // oxlint-disable-next-line typescript/no-unnecessary-condition -- Remote callers can submit untyped JSON. if (request.action.content.some(block => block.type !== 'text')) { throw new RemoteError( 'session/attachment-invalid', diff --git a/packages/api/session-controller/src/index.ts b/packages/api/session-controller/src/index.ts index 8bada7c33e..b6f5f0dfa0 100644 --- a/packages/api/session-controller/src/index.ts +++ b/packages/api/session-controller/src/index.ts @@ -2,6 +2,7 @@ import { hostname } from 'node:os' import { resolve } from 'node:path' +import type { Agent } from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-fs' import { Context } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' @@ -10,7 +11,7 @@ import type {} from '@deepseek-ai/dsh-client-file-upload' import { canOpenNativePath, nativeFileManager, openNativeAssociatedPath, revealNativePath } from '@deepseek-ai/dsh-native-command' import type { SessionId } from '@deepseek-ai/dsh-session' import type { SessionInspection } from '@deepseek-ai/dsh-session-persistence' -import type { SessionObservation } from '@deepseek-ai/dsh-session-query' +import { SessionQueryError, type SessionObservation } from '@deepseek-ai/dsh-session-query' import { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol' import { ApiSessionAgentController, @@ -53,6 +54,9 @@ import type { SessionSearchValue, SessionSelectModelRequest, SessionSelectModelValue, + SessionProjectionsRequest, + SessionProjectionsValue, + SessionProjectionValues, SessionUpdateQueueRequest, SessionUpdateQueueValue, } from './types.ts' @@ -152,6 +156,13 @@ export class SessionController extends TypertRemoteService { ctx.on('session/disposed', (session) => { ctx.emit('api-session/removed', session.id) }) + const publishAgentAvailability = ({ agent }: { agent: Agent }): undefined => { + if (ctx.sessions.get(agent.id) === agent.session) { + ctx.emit('api-session/added', this.listState.summaryFor(agent.session)) + } + } + ctx.on('agent/created', publishAgentAvailability) + ctx.on('agent/disposed', publishAgentAvailability) ctx.on('agent/status', ({ agent, status }) => { ctx.emit('api-session/status', agent.id, status === 'running') }) @@ -338,8 +349,10 @@ export class SessionController extends TypertRemoteService { } /** - * Fork one cold-readable completed-turn prefix into a new Session. - * @param request - source Session and optional event anchor. + * Fork one cold-readable exact event prefix into a new Session. An omitted + * boundary selects the latest completed-turn prefix; an open cut receives + * synthetic fork closers. + * @param request - source Session and optional exact inclusive event boundary. * @returns the new Session identity. */ @Remote('fork') @@ -412,6 +425,36 @@ export class SessionController extends TypertRemoteService { return this.history.follow(request, signal) } + /** + * Read all registered projections without activating an Agent. + * @param request - Session whose current values are required. + * @param signal - cancellation for the Session observation. + * @returns complete baseline, or null when the Session does not exist. + */ + @Remote('projections') + async projections(request: SessionProjectionsRequest, signal: AbortSignal): Promise { + const { sessionId } = request + if (sessionId.length === 0) { + throw new RemoteError('gateway/bad-request', 'sessionId must not be empty', {}) + } + try { + using observation = await this.ctx.sessionQuery.observeSession(sessionId, { signal }) + const projections = observation.projections + if (projections === undefined) { + throw new RemoteError('session/projections-unavailable', 'Session projections are unavailable', {}) + } + return { asOfSeq: projections.asOfSeq, values: projections.values as SessionProjectionValues } + } catch (error: unknown) { + if (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_SESSION_NOT_FOUND') return null + if (signal.aborted + || (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_ABORTED')) { + throw new RemoteError('gateway/cancelled', 'Session projection read was cancelled', {}, { cause: error }) + } + if (error instanceof RemoteError) throw error + throw new RemoteError('gateway/internal', 'Session projection read failed', {}, { cause: error }) + } + } + /** * Stream a complete live-control baseline followed by replacement frames. * @param signal - cancellation owned by the Remote stream carrier. diff --git a/packages/api/session-controller/src/list.ts b/packages/api/session-controller/src/list.ts index 4aa369c378..530414c52d 100644 --- a/packages/api/session-controller/src/list.ts +++ b/packages/api/session-controller/src/list.ts @@ -111,6 +111,7 @@ export class ApiSessionList { return { sessionId: session.id, updatedAt: updatedAt(session.header, metadata), + agentAvailable: this.ctx.agents.get(session.id)?.session === session, running: this.ctx.agents.get(session.id)?.status === 'running', blank: metadata?.blank ?? session.seq === 0, ...listFields(session.header), @@ -149,6 +150,7 @@ export class ApiSessionList { return { sessionId: header.id, updatedAt: updatedAt(header, metadata), + agentAvailable: false, running: false, // A large, metadata-less, or inaccessible cache miss remains unknown and visible. blank: metadata?.blank ?? false, diff --git a/packages/api/session-controller/src/types.ts b/packages/api/session-controller/src/types.ts index f03d8d1b65..a925e9da83 100644 --- a/packages/api/session-controller/src/types.ts +++ b/packages/api/session-controller/src/types.ts @@ -5,7 +5,7 @@ import type { } from '@deepseek-ai/dsh-attachment' import type { Branded } from '@deepseek-ai/dsh-brand' import type { LlmAttemptId, MessageId } from '@deepseek-ai/dsh-llm/brand' -import type { ContentBlock } from '@deepseek-ai/dsh-llm' +import type { TextBlock } from '@deepseek-ai/dsh-llm' import type { SessionId, SessionSeqCursor } from '@deepseek-ai/dsh-session/types' import type { SessionProjectionMap } from '@deepseek-ai/dsh-session-projection/types' import type { JobId } from '@deepseek-ai/dsh-jobs/brand' @@ -154,13 +154,15 @@ export type QueueAction = | { readonly kind: 'edit' /** Non-empty text-only replacement content. */ - readonly content: readonly ContentBlock[] + readonly content: readonly TextBlock[] } | { readonly kind: 'remove' } | { readonly kind: 'steer' } /** One Session list entry. */ export interface SessionSummary { + /** Whether this Session currently owns a live Agent. */ + readonly agentAvailable: boolean readonly sessionId: SessionId readonly updatedAt: number readonly running: boolean @@ -191,6 +193,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' { readonly requestedCwd: string readonly existingCwd?: string } + 'session/projections-unavailable': Record 'session/writer-held': { readonly sessionId: SessionId } 'session/agent-busy': { readonly reason: string } 'session/invalid-time-zone': { readonly value: string } @@ -301,6 +304,7 @@ export interface SessionRenameValue { /** Session fork request. */ export interface SessionForkRequest { readonly sessionId: SessionId + /** Exact inclusive source event seq; omission selects the latest completed-turn prefix. */ readonly atSeq?: number } @@ -392,6 +396,14 @@ export type SessionAddress = readonly mode: 'one-shot' | 'continuable' } +/** One non-activating Session projection read. */ +export interface SessionProjectionsRequest { + readonly sessionId: SessionId +} + +/** Complete Session projection baseline; null when the Session does not exist. */ +export type SessionProjectionsValue = SessionProjectionBaseline | null + /** One raw Session event in the Remote journal. */ export interface SessionEventEntry { readonly type: 'event' @@ -560,9 +572,10 @@ export type SessionControlFrame = declare module '@deepseek-ai/cordis' { interface Events { /** - * A Session became visible to Session list consumers. + * A Session became visible or its Agent was created or disposed. + * Consumers upsert the summary and replace its current running and availability state. * @mode emit - * @param summary - initial list row for the Session. + * @param summary - current list row for the Session. */ 'api-session/added'(summary: SessionSummary): void /** diff --git a/packages/api/session-controller/tests/client-apply.client.spec.ts b/packages/api/session-controller/tests/client-apply.client.spec.ts index bbb6e4836b..5323f64b17 100644 --- a/packages/api/session-controller/tests/client-apply.client.spec.ts +++ b/packages/api/session-controller/tests/client-apply.client.spec.ts @@ -51,7 +51,7 @@ describe('Session Controller Client apply', () => { // The first generation's `connection/reset` already ran it; apply itself saw no Host yet. await vi.waitFor(() => { expect(connected).toHaveBeenCalledOnce() }) - await emit(mock, 'api-session/added', { sessionId: sid('session-1'), updatedAt: 1, running: false, blank: true }) + await emit(mock, 'api-session/added', { agentAvailable: true, sessionId: sid('session-1'), updatedAt: 1, running: false, blank: true }) await vi.waitFor(() => { expect(sessions.list.getSnapshot().byId[sid('session-1')]).toMatchObject({ running: false, updatedAt: 1 }) }) @@ -84,7 +84,7 @@ describe('Session Controller Client apply', () => { const connected = vi.spyOn(ClientSessions.prototype, 'handleConnected') const sessionId = sid('immediate-baseline') mock.remote.session.list.mockResolvedValue(ok({ items: [{ - sessionId, updatedAt: 1, running: false, blank: false, + sessionId, updatedAt: 1, running: false, blank: false, agentAvailable: true, }] })) let projection = { asOfSeq: 20, values: { title: 'Before restart' } } mock.stream(CONTROL, (_args, stream) => { @@ -155,7 +155,7 @@ describe('Session Controller Client apply', () => { const { client, sessions } = await bench(start) await vi.waitFor(() => { expect(sessions.list.getSnapshot().phase).toBe('ready') }) - await emit(mock, 'api-session/added', { sessionId: sid('agent-1'), updatedAt: 1, running: false, blank: true }) + await emit(mock, 'api-session/added', { agentAvailable: true, sessionId: sid('agent-1'), updatedAt: 1, running: false, blank: true }) expect(sessions.scope(sid('agent-1'))).toBeUndefined() using reference = sessions.retainAgentScope(sid('agent-1')) const scoped = reference.binding.ctx diff --git a/packages/api/session-controller/tests/commands-create-fork.host.spec.ts b/packages/api/session-controller/tests/commands-create-fork.host.spec.ts index 2e3e8cc3b2..3baed6c3b6 100644 --- a/packages/api/session-controller/tests/commands-create-fork.host.spec.ts +++ b/packages/api/session-controller/tests/commands-create-fork.host.spec.ts @@ -221,6 +221,10 @@ describe('Session fork failures', () => { const controller = new SessionCommandController(ctx, controllerAgents(), '/default') await expectFailure(controller.fork({ sessionId: source.id }), 'session/fork-unavailable') + await expect(controller.fork({ sessionId: source.id, atSeq: 0 })).rejects.toMatchObject({ + code: 'session/fork-unavailable', + message: 'event 0 does not exist in session "empty-source" (last seq: none)', + }) await ctx.fiber.dispose() }) diff --git a/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts b/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts index 06c831db1c..3f1a45967d 100644 --- a/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts +++ b/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts @@ -5,6 +5,7 @@ import type { Agent, Inbox, ModelSelectionRef } from '@deepseek-ai/dsh-agent' import { AttachmentError, AttachmentId } from '@deepseek-ai/dsh-attachment' import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment' import { createAssistantMessage, createUserMessage, MessageId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SESSION_FORMAT_VERSION, Session, SessionId, SessionLogOffset, SessionSeq, } from '@deepseek-ai/dsh-session' @@ -17,6 +18,12 @@ import { SessionCommandController } from '../src/commands.ts' import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit' import { installSessionReadTestServices, testSessionPersistence } from './test-remote.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + async function commandHarness( childMode?: 'continuable' | 'seeded-continuable' | 'seed-only' | 'one-shot' | 'unknown' | 'corrupt', ): Promise<{ @@ -146,6 +153,7 @@ describe('Session queue commands', () => { action: { kind: 'edit', content: [{ + // @ts-expect-error -- remote edit payloads can carry unsupported image blocks. type: 'image', attachment: { attachmentId: AttachmentId('att-edit'), mediaType: 'image/png', bytes: 1, width: 1, height: 1, @@ -229,7 +237,7 @@ describe('Session queue commands', () => { content: [{ type: 'text', text: 'queued' }], source: { kind: 'user' }, }) const context = createUserMessage({ - content: [{ type: 'text', text: 'context' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'context' }], source: { kind: 'test' }, }) inbox.append('next-turn', queued) inbox.append('next-step', context) diff --git a/packages/api/session-controller/tests/control-queue.host.spec.ts b/packages/api/session-controller/tests/control-queue.host.spec.ts index 3a44506ea6..0c635753ea 100644 --- a/packages/api/session-controller/tests/control-queue.host.spec.ts +++ b/packages/api/session-controller/tests/control-queue.host.spec.ts @@ -1,6 +1,7 @@ import { Context } from '@deepseek-ai/cordis' import type { Agent, Inbox, InboxState } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import { afterEach, describe, expect, it } from 'vitest' import { SessionControlController } from '../src/control.ts' @@ -10,6 +11,12 @@ import { mountAgentLoopTestHarness, } from '@deepseek-ai/dsh-agent-loop-testkit' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'fixture': { kind: 'fixture' } & ContextFormed + } +} + const ownedContexts = new Set() afterEach(async () => { await Promise.all([...ownedContexts].map(ctx => ctx.fiber.dispose())) @@ -33,7 +40,7 @@ async function harness(): Promise<{ function message(text: string, source: 'user' | 'plugin' = 'user') { return createUserMessage({ content: [{ type: 'text', text }], - source: source === 'user' ? { kind: 'user' } : { kind: 'plugin', plugin: 'fixture' }, + source: source === 'user' ? { kind: 'user' } : { kind: 'fixture' }, }) } diff --git a/packages/api/session-controller/tests/event-script.client.ts b/packages/api/session-controller/tests/event-script.client.ts index 67a7c4026c..0e7eaed7d1 100644 --- a/packages/api/session-controller/tests/event-script.client.ts +++ b/packages/api/session-controller/tests/event-script.client.ts @@ -12,6 +12,19 @@ import type { SessionWireEvent, } from '../src/types.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'compact-checkpoint': { kind: 'compact-checkpoint'; compactionId: string } + } +} + +type CheckpointSource = { kind: 'compact-checkpoint'; compactionId: string } + +/** Build a typed checkpoint source for the history event script. */ +function checkpointSource(): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: 'event-script-compaction' } +} + /** One text content block (local helper). */ const text = (t: string): ContentBlock[] => [{ type: 'text', text: t }] @@ -149,7 +162,7 @@ export const ev = { sourceEventSeqs: [summarySeq, start, end], data: createUserMessage({ content: text('model only'), - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource(), }), }), } diff --git a/packages/api/session-controller/tests/inbox-projection.client.spec.ts b/packages/api/session-controller/tests/inbox-projection.client.spec.ts index 9f4ebfecda..589aa43d09 100644 --- a/packages/api/session-controller/tests/inbox-projection.client.spec.ts +++ b/packages/api/session-controller/tests/inbox-projection.client.spec.ts @@ -63,7 +63,7 @@ describe('Inbox projection intake', () => { const empty = { 'next-turn': [], 'next-step': [] } const stale = { ...empty, 'next-turn': [message('removed', 'already removed')] } const result = ok({ items: [{ - sessionId: SID, updatedAt: 1, running: false, blank: false, + sessionId: SID, updatedAt: 1, running: false, blank: false, agentAvailable: false, projections: { asOfSeq: 21, values: { inbox: empty } }, }] }) let refreshed: Promise | undefined @@ -108,9 +108,9 @@ describe('Inbox projection intake', () => { const face = manager.get(SID).projections.faceOf('inbox') const baseline = { type: 'baseline', value: { jobs: {}, projections: {} } } as const const result = ok({ items: [ - { sessionId: SID, updatedAt: 1, running: false, blank: false, + { sessionId: SID, updatedAt: 1, running: false, blank: false, agentAvailable: false, projections: { asOfSeq: 1, values: { inbox: empty } } }, - { sessionId: hiddenSessionId, updatedAt: 1, running: false, blank: false, + { sessionId: hiddenSessionId, updatedAt: 1, running: false, blank: false, agentAvailable: false, projections: { asOfSeq: 1, values: { inbox: restored } } }, ] }) let refreshed: Promise | undefined diff --git a/packages/api/session-controller/tests/lineage.client.spec.ts b/packages/api/session-controller/tests/lineage.client.spec.ts index 27080a8b2f..16f10c14f4 100644 --- a/packages/api/session-controller/tests/lineage.client.spec.ts +++ b/packages/api/session-controller/tests/lineage.client.spec.ts @@ -7,7 +7,7 @@ import { describe, expect, it, vi } from 'vitest' import type { SessionId, SessionSummary } from '@deepseek-ai/dsh-api-remotes/client' import { flattenLineage } from '../src/client/sessions/lineage.ts' -const s = (id: string, updatedAt: number, parent?: string): SessionSummary => ({ +const s = (id: string, updatedAt: number, parent?: string): SessionSummary => ({ agentAvailable: true, sessionId: id as SessionId, updatedAt, running: false, blank: false, ...(parent !== undefined ? { parentSessionId: parent as SessionId } : {}), }) diff --git a/packages/api/session-controller/tests/manager.client.spec.ts b/packages/api/session-controller/tests/manager.client.spec.ts index 2bbf54cc8e..7ee5be5397 100644 --- a/packages/api/session-controller/tests/manager.client.spec.ts +++ b/packages/api/session-controller/tests/manager.client.spec.ts @@ -23,12 +23,11 @@ const S2 = 'fk-m2' as SessionId /** Gateway Client cone used by the subagent-catalog and connected-generation cases. */ const API_ROSTER = webApp.closure(['@deepseek-ai/dsh-api-gateway']) const it = createClientTest({ roster: API_ROSTER }) -/** The first client boot pays the cold module transform of the api cone. */ -const COLD_BOOT_TIMEOUT_MS = 60_000 type SummaryOver = Partial<{ updatedAt: number running: boolean + agentAvailable: boolean blank: boolean cwd: string parentSessionId: SessionId @@ -36,7 +35,7 @@ type SummaryOver = Partial<{ }> function summary(sessionId: SessionId, over: SummaryOver = {}) { - return { sessionId, updatedAt: 100, running: false, blank: false, ...over } + return { agentAvailable: true, sessionId, updatedAt: 100, running: false, blank: false, ...over } } function makeManager( @@ -83,13 +82,13 @@ describe('SessionManager instances', () => { }) describe('SessionManager query lifetime', () => { - it.for(['list', 'catalog'] as const)('forwards an unexpected %s failure and still completes teardown', async (target, { mock, remote }) => { + it.for(['list', 'projection'] as const)('forwards an unexpected %s failure and still completes teardown', async (target, { mock, remote }) => { const manager = makeManager(mock, remote) const failure = new Error('query implementation failed') if (target === 'list') remote.session.list.mockRejectedValueOnce(failure) - else remote.subagents.list.mockRejectedValueOnce(failure) + else remote.session.projections.mockRejectedValueOnce(failure) try { - await expect(target === 'list' ? manager.refreshList() : manager.refreshSubagents(S1)).rejects.toBe(failure) + await expect(target === 'list' ? manager.refreshList() : manager.refreshProjections(S1)).rejects.toBe(failure) } finally { await manager.dispose() } @@ -107,43 +106,24 @@ describe('SessionManager query lifetime', () => { } }) - it.for([false, true])('preserves a rejected Remote catalog failure with prior baseline %s', async (warm, { mock, remote }) => { + it.for([false, true])('preserves a rejected Remote projection failure with prior values %s', async (warm, { mock, remote }) => { const manager = makeManager(mock, remote) - const failure = new RemoteError('gateway/internal', 'catalog unavailable', {}) - const entries = [{ kind: 'child' as const, id: S2, mode: 'one-shot' as const, activity: 'inactive' as const, hasChildren: false }] + const failure = new RemoteError('gateway/internal', 'projection unavailable', {}) + const entries = [{ id: S2, createdAt: 1, mode: 'one-shot' as const }] try { if (warm) { - remote.subagents.list.mockResolvedValueOnce(ok({ entries, parentAvailable: true })) - await manager.refreshSubagents(S1) - manager.handleSessionRemoved(S1) + manager.handleControlFrame({ type: 'projection', sessionId: S1, key: 'subagentCatalog', seq: 0, value: entries }) } - remote.subagents.list.mockRejectedValueOnce(failure) - const refresh = manager.refreshSubagents(S1) - await refresh - expect(manager.getListSnapshot().subagentsByParent[S1]).toMatchObject({ - state: 'error', error: failure, entries: warm ? entries : [], + remote.session.projections.mockRejectedValueOnce(failure) + await manager.refreshProjections(S1) + expect(manager.getListSnapshot().projectionsBySession[S1]).toMatchObject({ + state: 'error', error: failure, values: warm ? { subagentCatalog: entries } : {}, }) - expect(manager.getListSnapshot().subagentsByParent[S1]?.parentAvailable).toBe(warm ? false : undefined) } finally { await manager.dispose() } }) - it('cancels a queued catalog membership refresh when its consumer closes', async ({ mock, remote }) => { - vi.useFakeTimers() - const manager = makeManager(mock, remote) - try { - manager.setSubagentCatalogOpen(S1, true) - await manager.refreshSubagents(S1) - manager.handleSessionAdded(summary(S2, { parentSessionId: S1 })) - manager.setSubagentCatalogOpen(S1, false) - await vi.runAllTimersAsync() - expect(remote.subagents.list).toHaveBeenCalledOnce() - } finally { - await manager.dispose() - vi.useRealTimers() - } - }) }) describe('list lifecycle', () => { @@ -438,29 +418,27 @@ describe('Host Remote event routing', () => { describe('subagent catalogs', () => { it('keeps a catalog-discovered child address across identity resolution and status frames', async ({ mock, remote, start }) => { - remote.session.list.mockResolvedValue(ok({ items: [ + remote.session.list.mockImplementation(() => Promise.resolve(ok({ items: [ summary(S1), summary(S2, { parentSessionId: S1, origin: 'subagent' }), - ] as never[] })) - remote.subagents.list.mockResolvedValue(ok({ - entries: [{ - kind: 'child', id: S2, mode: 'continuable', label: 'worker', - activity: 'running', hasChildren: false, - }] as never[], - parentAvailable: true, - })) + ] as never[] }))) + remote.session.projections.mockImplementation(() => Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, + id: S2, mode: 'continuable', label: 'worker', + }] } }))) mock.load(sessionWorld) const client = await start() const manager = new SessionManager(client.ctx.remote) await manager.refreshList() - await manager.refreshSubagents(S1) + await manager.refreshProjections(S1) manager.resolveTarget({ parentSessionId: S1, childSessionId: S2, mode: 'continuable' }) expect(manager.subagentAddress(S2)).toEqual({ parentSessionId: S1, childSessionId: S2, mode: 'continuable', }) expect(manager.get(S2).getSnapshot().subagent).toEqual({ - address: { parentSessionId: S1, childSessionId: S2, mode: 'continuable' }, + address: { + parentSessionId: S1, childSessionId: S2, mode: 'continuable', + }, parentAvailable: true, }) // Clicking the same child through an ordinary list-selection path must not @@ -470,21 +448,26 @@ describe('subagent catalogs', () => { parentSessionId: S1, childSessionId: S2, mode: 'continuable', }) expect(manager.get(S2).getSnapshot().subagent).toEqual({ - address: { parentSessionId: S1, childSessionId: S2, mode: 'continuable' }, + address: { + parentSessionId: S1, childSessionId: S2, mode: 'continuable', + }, parentAvailable: true, }) await manager.get(S2).open() await manager.get(S2).prompt([{ type: 'text', text: 'continue' }], 'queue') - expect(remote.session.follow.mock.calls.map(([request]) => request)).toEqual([ + expect(mock.log.requests(FOLLOW)).toEqual([ { address: { - kind: 'subagent', parentSessionId: S1, childSessionId: S2, mode: 'continuable', + kind: 'subagent', + parentSessionId: S1, + childSessionId: S2, + mode: 'continuable', }, assistantStream: true, maxMessages: 50, }, ]) - expect(remote.session.page).not.toHaveBeenCalled() + expect(mock.log.requests('session/page')).toEqual([]) expect(remote.subagents.prompt.mock.calls.map(([request]) => request)).toEqual([ { requestId: expect.any(String) as unknown as string, @@ -495,13 +478,14 @@ describe('subagent catalogs', () => { clientTimeZone: new Intl.DateTimeFormat().resolvedOptions().timeZone, }, ]) - expect(remote.session.prompt).not.toHaveBeenCalled() - const listCalls = remote.subagents.list.mock.calls.length + expect(mock.log.requests('session/page')).toEqual([]) + expect(remote.session.prompt.mock.calls.map(([request]) => request)).toEqual([]) + const listCalls = remote.session.projections.mock.calls.map(([request]) => request).length manager.handleSessionStatus(S2, false) - expect(manager.getListSnapshot().subagentsByParent[S1]?.entries[0]).toMatchObject({ - kind: 'child', id: S2, activity: 'inactive', + expect(manager.getListSnapshot().projectionsBySession[S1]?.values.subagentCatalog?.[0]).toMatchObject({ + id: S2, }) - expect(remote.subagents.list).toHaveBeenCalledTimes(listCalls) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(listCalls) manager.handleSessionRemoved(S2) expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)).toMatchObject({ @@ -510,274 +494,172 @@ describe('subagent catalogs', () => { expect(manager.get(S2).getSnapshot()).toMatchObject({ removed: false, subagent: { - address: { parentSessionId: S1, childSessionId: S2, mode: 'continuable' }, + address: { + parentSessionId: S1, childSessionId: S2, mode: 'continuable', + }, }, }) - }, COLD_BOOT_TIMEOUT_MS) - - it('refetches debounced membership only while the parent catalog is open', async ({ mock, remote }) => { - vi.useFakeTimers() - try { - const manager = makeManager(mock, remote) - await manager.refreshSubagents(S1) - manager.setSubagentCatalogOpen(S1, true) - await Promise.resolve() - const baseline = remote.subagents.list.mock.calls.length - manager.handleSessionAdded(summary(S2, { parentSessionId: S1 })) - manager.handleSessionAdded(summary('fk-m3' as SessionId, { parentSessionId: S1 })) - await vi.advanceTimersByTimeAsync(50) - expect(remote.subagents.list).toHaveBeenCalledTimes(baseline + 1) - - manager.setSubagentCatalogOpen(S1, false) - manager.handleSessionAdded(summary('fk-m4' as SessionId, { parentSessionId: S1 })) - await vi.advanceTimersByTimeAsync(50) - expect(remote.subagents.list).toHaveBeenCalledTimes(baseline + 1) - } finally { - vi.useRealTimers() - } }) - it('marks a loaded parent row expandable only for a direct subagent publication', async ({ mock, remote }) => { - const root = 'fk-root' as SessionId - remote.subagents.list.mockResolvedValue(ok({ - entries: [ - { - kind: 'child', id: S1, mode: 'continuable', label: 'parent', - activity: 'inactive', hasChildren: false, - }, - { - kind: 'child', id: S2, mode: 'continuable', label: 'ordinary parent', - activity: 'inactive', hasChildren: false, - }, - ] as never[], - parentAvailable: true, - })) + it('publishes pushed membership without a catalog request or an instantiated parent', ({ mock, remote }) => { const manager = makeManager(mock, remote) - await manager.refreshSubagents(root) - - manager.handleSessionAdded(summary('fk-grandchild' as SessionId, { - parentSessionId: S1, origin: 'subagent', - })) - manager.handleSessionAdded(summary('fk-fork' as SessionId, { parentSessionId: S2 })) - - expect(manager.getListSnapshot().subagentsByParent[root]?.entries).toMatchObject([ - { kind: 'child', id: S1, hasChildren: true }, - { kind: 'child', id: S2, hasChildren: false }, + manager.handleSessionAdded(summary(S2, { origin: 'subagent', parentSessionId: S1, running: true })) + manager.handleControlFrame({ + type: 'projection', sessionId: S1, key: 'subagentCatalog', seq: 4, + value: [{ id: S2, createdAt: 1, mode: 'continuable', label: 'worker' }], + }) + expect(manager.getListSnapshot().projectionsBySession[S1]?.values.subagentCatalog).toEqual([ + { id: S2, createdAt: 1, mode: 'continuable', label: 'worker' }, ]) + expect(manager.subagentAddress(S2)).toEqual({ parentSessionId: S1, childSessionId: S2, mode: 'continuable' }) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toEqual([]) }) - it('preserves a live expandability hint across only the older in-flight catalog response', async ({ mock, remote }) => { - const root = 'fk-root' as SessionId - const response = Promise.withResolvers>>() - remote.subagents.list.mockReturnValue(response.promise) + it('keeps newer pushed membership when the initial read returns an older baseline', async ({ mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => response.promise) const manager = makeManager(mock, remote) - const refresh = manager.refreshSubagents(root) - - manager.handleSessionAdded(summary('fk-grandchild' as SessionId, { - parentSessionId: S1, origin: 'subagent', - })) - response.resolve(ok({ - entries: [{ - kind: 'child', id: S1, mode: 'continuable', label: 'parent', - activity: 'inactive', hasChildren: false, - }] as never[], - parentAvailable: true, - })) - await refresh - - expect(manager.getListSnapshot().subagentsByParent[root]?.entries).toMatchObject([ - { kind: 'child', id: S1, hasChildren: true }, - ]) - - remote.subagents.list.mockResolvedValue(ok({ - entries: [{ - kind: 'child', id: S1, mode: 'continuable', label: 'parent', - activity: 'inactive', hasChildren: false, - }] as never[], - parentAvailable: true, - })) - await manager.refreshSubagents(root) - expect(manager.getListSnapshot().subagentsByParent[root]?.entries).toMatchObject([ - { kind: 'child', id: S1, hasChildren: false }, - ]) + const read = manager.refreshProjections(S1) + manager.handleControlFrame({ + type: 'projection', sessionId: S1, key: 'subagentCatalog', seq: 5, + value: [{ id: S2, createdAt: 1, mode: 'continuable', label: 'pushed' }], + }) + response.resolve(ok({ asOfSeq: 3, values: { subagentCatalog: [] } })) + await read + expect(manager.getListSnapshot().projectionsBySession[S1]?.values.subagentCatalog?.[0]?.label).toBe('pushed') + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(1) }) - it('replays status frames over an older in-flight catalog response', async ({ mock, remote }) => { - const root = 'fk-root' as SessionId - const response = Promise.withResolvers>>() - remote.subagents.list.mockReturnValue(response.promise) + it.for([false, true])('keeps live parent availability when an earlier initial read settles (failure: %s)', async (failure, { mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => response.promise) const manager = makeManager(mock, remote) - const refresh = manager.refreshSubagents(root) - + manager.resolveTarget({ parentSessionId: S1, childSessionId: S2, mode: 'continuable' }) + const child = manager.get(S2) + const read = manager.refreshProjections(S1) + manager.handleSessionAdded(summary(S1)) manager.handleSessionStatus(S1, false) + response.resolve(failure + ? err(new RemoteError('gateway/internal', 'offline', {})) + : ok({ asOfSeq: 0, values: { subagentCatalog: [] } })) + await read + expect(child.getSnapshot().subagent?.parentAvailable).toBe(true) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(1) + }) + + it('keeps parent availability unknown after list failure and accepts a later Host summary', async ({ mock, remote }) => { + const manager = makeManager(mock, remote) + manager.resolveTarget({ parentSessionId: S1, childSessionId: S2, mode: 'continuable' }) + const child = manager.get(S2) + remote.session.list.mockResolvedValue(err(new RemoteError('gateway/internal', 'offline', {}))) + await manager.refreshList() + expect(manager.getListSnapshot().state).toBe('error') + expect(child.getSnapshot().subagent?.parentAvailable).toBeUndefined() + manager.handleSessionAdded(summary(S1)) + expect(child.getSnapshot().subagent?.parentAvailable).toBe(true) + await manager.dispose() + }) + + it('keeps a pushed catalog when an earlier initial read reports the parent missing', async ({ mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => response.promise) + const manager = makeManager(mock, remote) + const read = manager.refreshProjections(S1) + manager.handleControlFrame({ type: 'projection', sessionId: S1, key: 'subagentCatalog', seq: 1, + value: [{ id: S2, createdAt: 1, mode: 'one-shot' }] }) + response.resolve(ok(null)) + await read + expect(manager.getListSnapshot().projectionsBySession[S1]?.values.subagentCatalog).toEqual([ + { id: S2, createdAt: 1, mode: 'one-shot' }, + ]) + }) + + it('shares cold initial loading and reuses the loaded catalog when reopened', async ({ mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => response.promise) + const manager = makeManager(mock, remote) + const read = manager.refreshProjections(S1) + expect(manager.refreshProjections(S1)).toBe(read) + expect(manager.getListSnapshot().projectionsBySession[S1]?.state).toBe('loading') + response.resolve(ok({ asOfSeq: 0, values: { + subagentCatalog: [{ id: S2, createdAt: 1, mode: 'one-shot' }], + title: 'cold parent', + } })) + await read + await manager.refreshProjections(S1) + manager.handleSessionAdded(summary(S1)) + expect(manager.getListSnapshot().items[0]?.title).toBe('cold parent') + expect(manager.getListSnapshot().projectionsBySession[S1]).toMatchObject({ + values: { subagentCatalog: [{ id: S2, createdAt: 1, mode: 'one-shot' }] }, state: 'ready', + }) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(1) + }) + + it('uses current Session status rather than the time an initial catalog read started', async ({ mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => response.promise) + const manager = makeManager(mock, remote) + const read = manager.refreshProjections(S1) + manager.handleSessionAdded(summary(S2, { origin: 'subagent', parentSessionId: S1 })) manager.handleSessionStatus(S2, true) - response.resolve(ok({ - entries: [ - { - kind: 'child', id: S1, mode: 'continuable', label: 'stopped', - activity: 'running', hasChildren: false, - }, - { - kind: 'child', id: S2, mode: 'continuable', label: 'started', - activity: 'inactive', hasChildren: false, - }, - ] as never[], - parentAvailable: true, - })) - await refresh - - expect(manager.getListSnapshot().subagentsByParent[root]?.entries).toMatchObject([ - { kind: 'child', id: S1, activity: 'inactive' }, - { kind: 'child', id: S2, activity: 'running' }, - ]) + response.resolve(ok({ asOfSeq: 0, values: { + subagentCatalog: [{ id: S2, createdAt: 1, mode: 'continuable', label: 'worker' }], + } })) + await read + expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)?.running).toBe(true) + manager.handleSessionStatus(S2, false) + expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)?.running).toBe(false) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(1) }) - it('marks a detached catalog child inactive without requiring a selected address', async ({ mock, remote }) => { - remote.subagents.list.mockResolvedValue(ok({ - entries: [{ - kind: 'child', id: S2, mode: 'continuable', label: 'worker', - activity: 'running', hasChildren: false, - }] as never[], - parentAvailable: true, - })) + it('keeps completed unselected child metadata with its durable catalog row', ({ mock, remote }) => { const manager = makeManager(mock, remote) - await manager.refreshSubagents(S1) - + manager.handleSessionAdded(summary(S2, { origin: 'subagent', parentSessionId: S1, running: true })) + manager.handleControlFrame({ type: 'projection', sessionId: S2, key: 'title', value: 'finished child', seq: 2 }) + manager.handleControlFrame({ type: 'projection', sessionId: S1, key: 'subagentCatalog', seq: 1, + value: [{ id: S2, createdAt: 1, mode: 'one-shot' }] }) manager.handleSessionRemoved(S2) - - expect(manager.getListSnapshot().subagentsByParent[S1]?.entries).toMatchObject([ - { kind: 'child', id: S2, activity: 'inactive' }, - ]) + expect(manager.getListSnapshot().items[0]).toMatchObject({ title: 'finished child', running: false }) + expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)?.running).toBe(false) }) - it('coalesces overlapping catalog reads without scheduling a trailing pull', async ({ mock, remote }) => { - const root = 'fk-root' as SessionId - const first = Promise.withResolvers>>() - remote.subagents.list.mockReturnValue(first.promise) + it('does not invent membership from Session summaries', ({ mock, remote }) => { const manager = makeManager(mock, remote) - - const refresh = manager.refreshSubagents(root) - expect(manager.refreshSubagents(root)).toBe(refresh) - remote.subagents.list.mockResolvedValue(ok({ entries: [], parentAvailable: true })) - first.resolve(ok({ entries: [], parentAvailable: true })) - await refresh - - expect(remote.subagents.list).toHaveBeenCalledOnce() + manager.handleSessionAdded(summary(S2, { origin: 'subagent', parentSessionId: S1 })) + expect(manager.getListSnapshot().projectionsBySession[S1]).toBeUndefined() }) - it('runs one trailing catalog refresh for a membership change coalesced into an in-flight pull', async ({ mock, remote }) => { - vi.useFakeTimers() - try { - const root = 'fk-root' as SessionId - const first = Promise.withResolvers>>() - const second = Promise.withResolvers>>() - remote.subagents.list.mockReturnValue(first.promise) - const manager = makeManager(mock, remote) - const refresh = manager.refreshSubagents(root) - manager.setSubagentCatalogOpen(root, true) - - // A membership frame arrives while the pull is in flight; the debounced - // refresh it schedules fires 50ms later and is coalesced into the pull — - // which was requested before the new child existed. The stale mark must - // queue one trailing pull carrying the change. - manager.handleSessionAdded(summary(S2, { parentSessionId: root })) - await vi.advanceTimersByTimeAsync(50) - remote.subagents.list.mockReturnValueOnce(second.promise) - first.resolve(ok({ - entries: [{ - kind: 'child', id: S1, mode: 'continuable', label: 'older', - activity: 'inactive', hasChildren: false, - }] as never[], - parentAvailable: true, - })) - await refresh - // The trailing pull is already in flight (kicked synchronously in finally). - second.resolve(ok({ - entries: [ - { - kind: 'child', id: S1, mode: 'continuable', label: 'older', - activity: 'inactive', hasChildren: false, - }, - { - kind: 'child', id: S2, mode: 'continuable', label: 'new child', - activity: 'inactive', hasChildren: false, - }, - ] as never[], - parentAvailable: true, - })) - await second.promise - // The Remote face resolves one microtask after the response settles. - await vi.advanceTimersByTimeAsync(0) - - expect(remote.subagents.list).toHaveBeenCalledTimes(2) - expect(manager.getListSnapshot().subagentsByParent[root]?.entries).toMatchObject([ - { kind: 'child', id: S1, label: 'older' }, - { kind: 'child', id: S2, label: 'new child' }, - ]) - } finally { - vi.useRealTimers() - } + it('retries a failed initial read without discarding pushed entries', async ({ mock, remote }) => { + remote.session.projections.mockImplementation(() => Promise.resolve(err(new RemoteError('gateway/internal', 'offline', {})))) + const manager = makeManager(mock, remote) + manager.handleControlFrame({ type: 'projection', sessionId: S1, key: 'subagentCatalog', seq: 2, + value: [{ id: S2, createdAt: 1, mode: 'one-shot' }] }) + await manager.refreshProjections(S1) + expect(manager.getListSnapshot().projectionsBySession[S1]).toMatchObject({ state: 'error', values: { subagentCatalog: [{ id: S2 }] } }) + remote.session.projections.mockImplementation(() => Promise.resolve(ok({ asOfSeq: 2, values: { subagentCatalog: [] } }))) + await manager.refreshProjections(S1) + expect(manager.getListSnapshot().projectionsBySession[S1]).toMatchObject({ state: 'ready', values: { subagentCatalog: [{ id: S2 }] } }) }) - it('keeps removal invalidation across a stale success and failed trailing pull', async ({ mock, remote }) => { - const root = 'fk-root' as SessionId - const child = () => ({ - kind: 'child' as const, id: S2, mode: 'continuable' as const, label: 'worker', - activity: 'inactive' as const, hasChildren: false, + it('ignores a late response after parent removal without a trailing request', async ({ mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => response.promise) + const manager = makeManager(mock, remote) + const read = manager.refreshProjections(S1) + manager.handleSessionRemoved(S1) + response.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [] } })) + await read + expect(manager.getListSnapshot().items.some(item => item.sessionId === S1)).toBe(false) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(1) + }) + + it('represents a missing parent as an empty unavailable catalog', async ({ mock, remote }) => { + remote.session.projections.mockImplementation(() => Promise.resolve(ok(null))) + const manager = makeManager(mock, remote) + await manager.refreshProjections(S1) + expect(manager.getListSnapshot().projectionsBySession[S1]).toEqual({ + values: {}, state: 'ready', error: null, }) - const first = Promise.withResolvers>>() - remote.subagents.list.mockReturnValue(first.promise) - const manager = makeManager(mock, remote) - const refresh = manager.refreshSubagents(root) - first.resolve(ok({ entries: [child()] as never[], parentAvailable: true })) - await refresh - manager.resolveTarget({ parentSessionId: root, childSessionId: S2, mode: 'continuable' }) - - // The removal lands while a second pull is in flight: the invalidation - // must survive the pre-removal ok response, so one trailing pull runs. - const mid = Promise.withResolvers>>() - remote.subagents.list.mockReturnValueOnce(mid.promise) - const midRefresh = manager.refreshSubagents(root) - manager.handleSessionRemoved(root) - const trailing = Promise.withResolvers>>() - remote.subagents.list.mockReturnValueOnce(trailing.promise) - mid.resolve(ok({ entries: [child()] as never[], parentAvailable: true })) - await midRefresh - expect(manager.getListSnapshot().subagentsByParent[root]?.parentAvailable).toBe(false) - expect(manager.get(S2).getSnapshot().subagent).toMatchObject({ parentAvailable: false }) - - trailing.resolve(err(new RemoteError('gateway/internal', 'trailing pull failed', {}))) - await vi.waitFor(() => { - expect(manager.getListSnapshot().subagentsByParent[root]).toMatchObject({ - state: 'error', - parentAvailable: false, - }) - }) - - const rootCalls = remote.subagents.list.mock.calls.filter(([call]) => call === root) - expect(rootCalls).toHaveLength(3) - expect(manager.getListSnapshot().subagentsByParent[root]?.parentAvailable).toBe(false) - expect(manager.get(S2).getSnapshot().subagent).toMatchObject({ parentAvailable: false }) - }) - - it('invalidates catalog availability when the owning parent is removed', async ({ mock, remote }) => { - const root = 'fk-root' as SessionId - remote.subagents.list.mockResolvedValue(ok({ - entries: [{ - kind: 'child', id: S2, mode: 'continuable', label: 'worker', - activity: 'inactive', hasChildren: false, - }] as never[], - parentAvailable: true, - })) - const manager = makeManager(mock, remote) - await manager.refreshSubagents(root) - manager.resolveTarget({ parentSessionId: root, childSessionId: S2, mode: 'continuable' }) - expect(manager.get(S2).getSnapshot().subagent).toMatchObject({ parentAvailable: true }) - - manager.handleSessionRemoved(root) - - expect(manager.getListSnapshot().subagentsByParent[root]?.parentAvailable).toBe(false) - expect(manager.get(S2).getSnapshot().subagent).toMatchObject({ parentAvailable: false }) }) }) @@ -811,6 +693,39 @@ describe('remaining branches', () => { expect(await manager.create()).toMatchObject({ ok: false }) }) + it.for(['create', 'fork'] as const)('preserves pushed running state when a %s response arrives later', async (operation, { mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session[operation].mockImplementation(() => response.promise) + const manager = makeManager(mock, remote) + const request = operation === 'create' ? manager.create() : manager.fork({ sessionId: S1 }) + manager.handleSessionAdded(summary(S2, { running: true })) + response.resolve(ok({ sessionId: S2 })) + await request + expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)) + .toMatchObject({ running: true }) + manager.handleSessionAdded(summary(S2, { running: false, agentAvailable: false })) + expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)) + .toMatchObject({ running: false }) + await manager.dispose() + }) + + it('preserves Host availability when a local create echo follows Agent disposal', async ({ mock, remote }) => { + const response = Promise.withResolvers>>() + remote.session.create.mockImplementation(() => response.promise) + const manager = makeManager(mock, remote) + manager.resolveTarget({ + parentSessionId: S1, childSessionId: S2, mode: 'continuable', + }) + const child = manager.get(S2) + const request = manager.create() + manager.handleSessionAdded(summary(S1, { agentAvailable: false })) + response.resolve(ok({ sessionId: S1 })) + await request + manager.resolveTarget(S2) + expect(child.getSnapshot().subagent?.parentAvailable).toBe(false) + await manager.dispose() + }) + it('publishes a real Ungrouped summary from workspace-attach-failed', async ({ mock, remote }) => { remote.session.create.mockResolvedValue(err(new RemoteError('session/workspace-attach-failed', 'published but unattached', { sessionId: S1, workspaceId: 'w1', @@ -832,8 +747,13 @@ describe('remaining branches', () => { expect(manager.getListSnapshot().items).toEqual([expect.objectContaining({ sessionId: S2, parentSessionId: S1, - blank: false, + blank: true, })]) + + manager.handleSessionAdded(summary(S2, { blank: true, parentSessionId: S1 })) + expect(manager.getListSnapshot().items[0]?.blank).toBe(true) + manager.handleSessionAdded(summary(S2, { blank: false, parentSessionId: S1 })) + expect(manager.getListSnapshot().items[0]?.blank).toBe(false) }) it('reconciles a preallocated id after an ordinary transport failure', async ({ mock, remote }) => { @@ -1021,6 +941,55 @@ describe('connected generation', () => { } }) + it.for([false, true])('refreshes an unselected cached catalog after offline activity changes: %s', async (running, { mock, remote }) => { + let hostRunning = !running + remote.session.list.mockImplementation(() => Promise.resolve(ok({ items: [ + summary(S1), + summary(S2, { parentSessionId: S1, origin: 'subagent', running: hostRunning }), + ] as never[] }))) + remote.session.projections.mockImplementation(() => Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, id: S2, mode: 'continuable', label: 'worker' }] } }))) + const manager = makeManager(mock, remote) + try { + await manager.refreshList() + await manager.refreshProjections(S1) + const reads = remote.session.projections.mock.calls.map(([request]) => request).length + hostRunning = running + manager.handleConnected() + await manager.refreshList() + await vi.waitFor(() => { + expect(manager.getListSnapshot().items.find(item => item.sessionId === S2)?.running) + .toBe(running) + }) + expect(manager.getListSnapshot()).not.toHaveProperty('current') + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(reads + 1) + } finally { + await manager.dispose() + } + }) + + it('starts a fresh catalog read on reconnect and ignores the previous response', async ({ mock, remote }) => { + const previous = Promise.withResolvers>>() + remote.session.projections + .mockReturnValueOnce(previous.promise) + .mockResolvedValue(ok({ asOfSeq: 0, values: { subagentCatalog: [] } })) + const manager = makeManager(mock, remote) + try { + const read = manager.refreshProjections(S1) + manager.handleConnected() + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(2) + previous.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, id: S2, mode: 'continuable', label: 'worker' }] } })) + await read + await vi.waitFor(() => { + expect(manager.getListSnapshot().projectionsBySession[S1]).toMatchObject({ + values: {}, state: 'ready', + }) + }) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toHaveLength(2) + } finally { + await manager.dispose() + } + }) + it('refreshes query baselines without rebuilding independently resumed Session sources', async ({ mock, remote, start }) => { mock.stream(FOLLOW, followScript(ok({ records: entries(plainTurn(SessionSeq(0), 0, 'a', 'b')) as never[], @@ -1043,31 +1012,30 @@ describe('connected generation', () => { it('retains the durable parent address and refreshes that parent across reconnect', async ({ mock, remote }) => { const address = { - parentSessionId: S1, childSessionId: S2, mode: 'continuable' as const, + parentSessionId: S1, + childSessionId: S2, + mode: 'continuable' as const, } - const parent = Promise.withResolvers>>() - const child = Promise.withResolvers>>() - remote.subagents.list.mockImplementation(payload => (payload === S1 ? parent.promise : child.promise)) + remote.session.list.mockImplementation(() => Promise.resolve(ok({ items: [summary(S1)] as never[] }))) + const parent = Promise.withResolvers>>() + remote.session.projections.mockImplementation(() => parent.promise) const manager = makeManager(mock, remote) - remote.subagents.list.mockResolvedValueOnce(ok({ - entries: [{ kind: 'child', id: S2, mode: 'continuable', label: 'worker', activity: 'inactive', hasChildren: false }], - parentAvailable: true, - })) - await manager.refreshSubagents(S1) manager.resolveTarget(address) manager.get(S2) - remote.subagents.list.mockClear() manager.handleConnected() - expect(manager.get(S2).getSnapshot().subagent).toEqual({ address, parentAvailable: true }) - parent.resolve(ok({ entries: [], parentAvailable: true })) - child.resolve(ok({ entries: [], parentAvailable: true })) + expect(manager.get(S2).getSnapshot().subagent).toEqual({ address }) + parent.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, + id: S2, mode: 'continuable', label: 'worker', + }] } })) await vi.waitFor(() => { - expect(remote.session.list).toHaveBeenCalledOnce() + expect(remote.session.list.mock.calls.map(([request]) => request)).toHaveLength(1) }) await vi.waitFor(() => { - expect(remote.subagents.list.mock.calls.map(([parentSessionId]) => parentSessionId)).toEqual([S1]) + expect(remote.session.projections.mock.calls.map(([request]) => request)).toEqual([ + { sessionId: S1 }, + ]) }) expect(manager.get(S2).getSnapshot().subagent).toEqual({ address, diff --git a/packages/api/session-controller/tests/projection-store.client.spec.ts b/packages/api/session-controller/tests/projection-store.client.spec.ts index b943557ca4..2ab2bbaec6 100644 --- a/packages/api/session-controller/tests/projection-store.client.spec.ts +++ b/packages/api/session-controller/tests/projection-store.client.spec.ts @@ -187,7 +187,7 @@ describe('manager frame routing', () => { it('preserves a newer title when the control baseline omits it', async ({ mock, remote }) => { const manager = makeManager(mock, remote) remote.session.list.mockResolvedValue(ok({ - items: [{ sessionId: sid('s1'), updatedAt: 1, running: false, blank: false }], + items: [{ agentAvailable: true, sessionId: sid('s1'), updatedAt: 1, running: false, blank: false }], })) await manager.refreshList() manager.handleControlFrame({ @@ -209,7 +209,7 @@ describe('manager frame routing', () => { it('projects every retained value into list rows with stable snapshot identity', async ({ mock, remote }) => { const manager = makeManager(mock, remote) remote.session.list.mockResolvedValue(ok({ - items: [{ + items: [{ agentAvailable: true, sessionId: sid('s1'), updatedAt: 1, running: false, blank: false, projections: { asOfSeq: 2, @@ -232,16 +232,21 @@ describe('manager frame routing', () => { expect(manager.getListSnapshot().items[0]?.projectionValues).not.toBe(baseline) }) - it('drops the projection store with the removed session', async ({ mock, remote }) => { + it.for([undefined, []])('drops the removed ordinary Session store with catalog %s', async (catalog, { mock, remote }) => { const manager = makeManager(mock, remote) remote.session.list.mockResolvedValue(ok({ - items: [{ sessionId: sid('s1'), updatedAt: 1, running: false, blank: false }], + items: [{ agentAvailable: true, sessionId: sid('s1'), updatedAt: 1, running: false, blank: false }], })) await manager.refreshList() manager.handleControlFrame({ type: 'projection', sessionId: sid('s1'), key: 'title', value: 'Doomed', seq: 4, }) + if (catalog !== undefined) { + manager.handleControlFrame({ type: 'projection', sessionId: sid('s1'), key: 'subagentCatalog', value: catalog, seq: 4 }) + } manager.handleSessionRemoved(sid('s1')) + expect(manager.getListSnapshot().projectionsBySession[sid('s1')]).toBeUndefined() expect(manager.get(sid('s1')).projections.get('title')).toBeUndefined() + await manager.dispose() }) }) diff --git a/packages/api/session-controller/tests/reference-ownership.client.spec.ts b/packages/api/session-controller/tests/reference-ownership.client.spec.ts index c1d0f74065..25253dfc24 100644 --- a/packages/api/session-controller/tests/reference-ownership.client.spec.ts +++ b/packages/api/session-controller/tests/reference-ownership.client.spec.ts @@ -36,7 +36,7 @@ async function bench(mock: RemoteMock, start: () => Promise, listed mock.stream(FOLLOW, followScript(EMPTY_HISTORY)) const feed = async (include: boolean): Promise => { mock.remote.session.list.mockResolvedValue(ok({ items: include - ? [{ sessionId: ID, updatedAt: 1, running: false, blank: true }] + ? [{ sessionId: ID, updatedAt: 1, running: false, blank: true, agentAvailable: true }] : [] })) await svc.refresh() } @@ -140,7 +140,7 @@ describe('Client reference sources', () => { expect(b.svc.list.getSnapshot().ids).not.toContain(ID) expect(b.svc.list.getSnapshot().byId[ID]?.retainedBy).toEqual({ gateway: 1 }) expect(mock.log.requests(FOLLOW)).toHaveLength(0) - expect(mock.remote.subagents.list).not.toHaveBeenCalled() + expect(mock.remote.session.projections).not.toHaveBeenCalled() await b.feed(true) expect(b.svc.list.getSnapshot().byId[ID]?.retainedBy).toEqual({ gateway: 1 }) }) diff --git a/packages/api/session-controller/tests/remote/session.client.ts b/packages/api/session-controller/tests/remote/session.client.ts index b4cd74676c..4d86abcf9e 100644 --- a/packages/api/session-controller/tests/remote/session.client.ts +++ b/packages/api/session-controller/tests/remote/session.client.ts @@ -145,7 +145,7 @@ export const sessionWorld: RemoteTable = { data: 'AA==', }), 'session/page': pageRule(ok({ records: [], hasMore: false })), - 'subagents/list': ok({ entries: [], parentAvailable: true }), + 'session/projections': ok({ asOfSeq: -1, values: { subagentCatalog: [] } }), 'subagents/prompt': ok({ messageId: 'fake-message' }), 'subagents/interruptByParent': ok({ accepted: true }), }, diff --git a/packages/api/session-controller/tests/session-cold.host.spec.ts b/packages/api/session-controller/tests/session-cold.host.spec.ts index c89ae1f97a..c8be6f2252 100644 --- a/packages/api/session-controller/tests/session-cold.host.spec.ts +++ b/packages/api/session-controller/tests/session-cold.host.spec.ts @@ -282,12 +282,12 @@ describe('Remote Agent and Session lookup policy', () => { content: [{ type: 'text', text: 'survives restart' }], source: { kind: 'user' }, }) - const events = [{ + const events: SessionEvent[] = [{ type: 'agent/inbox/spliced', - seq: 0, + seq: SessionSeq(0), time: 1001, data: { target: 'next-turn', start: 0, inserted: [message] }, - }] as SessionEvent[] + }] providePersistence(ctx, { list: () => Promise.resolve([meta]), inspect: () => Promise.resolve({ meta, events }), diff --git a/packages/api/session-controller/tests/session-fork.host.spec.ts b/packages/api/session-controller/tests/session-fork.host.spec.ts index 346ec758a1..c2cba32d55 100644 --- a/packages/api/session-controller/tests/session-fork.host.spec.ts +++ b/packages/api/session-controller/tests/session-fork.host.spec.ts @@ -5,18 +5,23 @@ import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { agentEvents } from '@deepseek-ai/dsh-agent' import type { Agent, AgentHandle, CreateAgentOptions } from '@deepseek-ai/dsh-agent' import { mountAgentLoopTestDependencies, mountAgentLoopTestHarness } from '@deepseek-ai/dsh-agent-loop-testkit' +import { BasicCompactionEngine } from '@deepseek-ai/dsh-compaction-basic' import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' -import { createUserMessage, ReasoningEffortId } from '@deepseek-ai/dsh-llm' +import { ToolCallId, createMessage, createUserMessage, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import type { LlmCallConfig } from '@deepseek-ai/dsh-llm' -import SessionStore, { SESSION_FORMAT_VERSION, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' +import SessionStore, { TOOL_OUTCOME_UNKNOWN, SESSION_FORMAT_VERSION, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' +import TokenMeter from '@deepseek-ai/dsh-token-meter' import type { Workspace } from '@deepseek-ai/dsh-workspace' import { createSessionTestRemote, installSessionReadTestServices, testSessionPersistence, } from './test-remote.ts' const sid = (id: string): SessionId => id as SessionId +const message = (text: string) => createUserMessage({ + content: [{ type: 'text', text }], source: { kind: 'user' }, +}) function request

(payload: P): P { return payload @@ -90,7 +95,49 @@ const remote = (ctx: Context) => createSessionTestRemote(ctx, { }) describe('sessions.fork', () => { - it.each(['message', 'turn-end', 'omitted', 'past-end'] as const)( + it('keeps the completed manual compaction checkpoint when atSeq is omitted', async () => { + const ctx = new Context() + try { + await mountAgentLoopTestDependencies(ctx) + const harness = await mountAgentLoopTestHarness(ctx) + await ctx.plugin(TokenMeter) + const compact = new BasicCompactionEngine(ctx, { auto: false }) + const adapter = new MockAdapter([ + textResponse('reply'), textResponse('checkpoint'), textResponse('continued'), + ]) + ctx.llm.registerAdapter(['mock'], adapter) + ctx.provide('workspaceRegistry', { list: () => [] } as never) + const source = await harness.create(sid('manual-compaction-source'), { provider: 'mock', model: 'mock' }) + const originalPrompt = 'older conversation history '.repeat(60) + source.followup(message(originalPrompt)) + await source.whenIdle() + expect(await compact.compactNow(source, new AbortController().signal)).not.toBeNull() + const compacted = source.session.snapshotEvents() + expect(compacted.at(-1)).toMatchObject({ type: 'compaction/end', data: { turn: null } }) + source.inbox.append('next-turn', message('queued after compaction')) + + const response = await createSessionTestRemote(ctx, { + defaultModelSelection: () => ({ provider: 'mock', model: 'mock' }), cwd: '/tmp', + }).fork({ sessionId: source.id }) + + if (!response.ok) throw response.error + const child = ctx.agents.get(response.value.sessionId)! + expect(child.session.inheritedEventCount).toBe(compacted.length) + expect(child.session.snapshotEvents().slice(0, child.session.inheritedEventCount)).toEqual(compacted) + expect(child.session.deriveMessages()).toEqual(source.session.deriveMessages()) + child.followup(message('continue from checkpoint')) + await child.whenIdle() + const requestText = JSON.stringify(adapter.requests.at(-1)?.messages) + expect(requestText).toContain('checkpoint') + expect(requestText).toContain('continue from checkpoint') + expect(requestText).not.toContain(originalPrompt) + expect(requestText).not.toContain('queued after compaction') + } finally { + await ctx.fiber.dispose() + } + }) + + it.each(['turn-end', 'omitted'] as const)( 'excludes the next user input when forking at %s', async (anchor) => { const ctx = new Context() try { @@ -100,23 +147,17 @@ describe('sessions.fork', () => { ctx.llm.registerAdapter(['mock'], adapter) ctx.provide('workspaceRegistry', { list: () => [] } as never) const source = await harness.create(sid('source'), { provider: 'mock', model: 'mock' }) - const message = (text: string) => createUserMessage({ - content: [{ type: 'text', text }], source: { kind: 'user' }, - }) source.followup(message('A')) await source.whenIdle() const boundary = source.session.snapshotEvents().at(-1)!.seq - if (anchor === 'message' || anchor === 'turn-end') { + if (anchor === 'turn-end') { source.followup(message('B')) await source.whenIdle() } else { source.inbox.append('next-turn', message('B')) } const original = source.session.snapshotEvents() - const atSeq = anchor === 'omitted' ? undefined - : anchor === 'past-end' ? source.session.seq + 1 - : anchor === 'turn-end' ? boundary - : original.find(event => event.type === 'assistant/message')!.seq + const atSeq = anchor === 'omitted' ? undefined : boundary const response = await createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'mock', model: 'mock' }), cwd: '/tmp', }).fork({ sessionId: source.id, ...(atSeq === undefined ? {} : { atSeq }) }) @@ -137,10 +178,10 @@ describe('sessions.fork', () => { }, ) - it('cuts at the anchored completed turn and records lineage and cwd', async () => { + it('cuts exactly at a completed turn and records lineage and cwd', async () => { const ctx = await composed() const source = await liveAgent(ctx, 'session-source', 2) - const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: 1 })) + const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: 2 })) expect(response.ok ? null : response.error).toBeNull() if (!response.ok) return const child = ctx.sessions.get(response.value.sessionId) @@ -184,7 +225,7 @@ describe('sessions.fork', () => { const response = await remote(ctx).fork(request({ sessionId: grandchild.id })) - expect(response.ok).toBe(true) + expect(response.ok ? undefined : response.error).toBeUndefined() if (!response.ok) return expect(attachSession).toHaveBeenCalledWith(response.value.sessionId) expect(ctx.sessions.get(response.value.sessionId)?.header).toMatchObject({ @@ -239,7 +280,7 @@ describe('sessions.fork', () => { const response = await remote(ctx).fork(request({ sessionId: sourceId })) - expect(response.ok).toBe(true) + expect(response.ok ? undefined : response.error).toBeUndefined() if (!response.ok) return expect(resume).not.toHaveBeenCalled() expect(ctx.agents.get(sourceId)).toBeUndefined() @@ -251,30 +292,62 @@ describe('sessions.fork', () => { await ctx.fiber.dispose() }) - it('uses the last completed turn only for omitted and past-end anchors', async () => { + it('uses the latest completed prefix only when atSeq is omitted', async () => { const ctx = await composed() const source = await liveAgent(ctx, 'session-tail', 2, 'open') const proxy = remote(ctx) - const expectedTypes = [ - 'turn/start', 'user/message', 'turn/end', - 'turn/start', 'user/message', 'turn/end', - 'session/end-seed', - ] const omitted = await proxy.fork(request({ sessionId: source.id })) expect(omitted.ok).toBe(true) if (omitted.ok) { expect(ctx.sessions.get(omitted.value.sessionId)?.snapshotEvents().map(event => event.type)) - .toEqual(expectedTypes) + .toEqual([ + 'turn/start', 'user/message', 'turn/end', + 'turn/start', 'user/message', 'turn/end', + 'session/end-seed', + ]) } const pastEnd = await proxy.fork(request({ sessionId: source.id, atSeq: 999 })) - expect(pastEnd.ok).toBe(true) - if (pastEnd.ok) { - expect(ctx.sessions.get(pastEnd.value.sessionId)?.snapshotEvents().map(event => event.type)) - .toEqual(expectedTypes) - } + expect(pastEnd).toMatchObject({ + ok: false, + error: { code: 'session/fork-unavailable', details: { sessionId: source.id } }, + }) + if (!pastEnd.ok) expect(pastEnd.error.message).toMatch(/does not exist/) await ctx.fiber.dispose() }) + it('rejects an omitted boundary when no turn has completed', async () => { + const ctx = await composed() + const source = await liveAgent(ctx, 'session-never-completed', 0, 'open') + const response = await remote(ctx).fork(request({ sessionId: source.id })) + expect(response).toMatchObject({ + ok: false, + error: { code: 'session/fork-unavailable', details: { sessionId: source.id } }, + }) + if (!response.ok) expect(response.error.message).toMatch(/no completed turn/) + await ctx.fiber.dispose() + }) + + it.each([false, true])('inherits standalone tail events with the next turn open: %s', async (openNextTurn) => { + const ctx = await composed() + try { + const source = await liveAgent(ctx, 'session-standalone-tail', 1) + source.append('session/title', { title: 'After the turn', messageSeqs: [], source: { kind: 'user' } }) + const inherited = source.snapshotEvents() + if (openNextTurn) source.append('turn/start', { turn: 2 }) + + const response = await remote(ctx).fork({ sessionId: source.id }) + + if (!response.ok) throw response.error + const child = ctx.sessions.get(response.value.sessionId)! + expect(child.inheritedEventCount).toBe(inherited.length) + expect(child.snapshotEvents().slice(0, child.inheritedEventCount)).toEqual(inherited) + expect(child.snapshotEvents().slice(child.inheritedEventCount).map(event => event.type)) + .toEqual(['session/end-seed']) + } finally { + await ctx.fiber.dispose() + } + }) + it('rejects invalid fork anchors before reading or creating a Session', async () => { const ctx = await composed() const proxy = remote(ctx) @@ -287,33 +360,128 @@ describe('sessions.fork', () => { await ctx.fiber.dispose() }) - it('cuts through an aborted turn: stopped is closed, not open', async () => { + it('cuts before an aborted turn/end and synthesizes a forked closer', async () => { const ctx = await composed() const source = await liveAgent(ctx, 'session-aborted', 1, 'aborted') - // What a stopped message's fork button anchors on: the frozen node sits - // one event before its turn/end, floored client-side to that event's seq. const anchor = (source.snapshotEvents().at(-1)?.seq ?? 0) - 1 const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: anchor })) - expect(response.ok).toBe(true) + expect(response.ok ? undefined : response.error).toBeUndefined() + if (!response.ok) return + const child = ctx.sessions.get(response.value.sessionId) + expect(child?.snapshotEvents().map(event => event.type)).toEqual([ + 'turn/start', 'user/message', 'turn/end', + 'turn/start', 'user/message', 'session/end-seed', 'turn/end', + ]) + const closer = child?.snapshotEvents().at(-1) + expect(closer?.type === 'turn/end' && closer.data.reason).toEqual({ kind: 'forked' }) + await ctx.fiber.dispose() + }) + + it('cuts exactly inside a live open turn and preserves the source', async () => { + const ctx = await composed() + const source = await liveAgent(ctx, 'session-open', 1, 'open') + const boundary = source.snapshotEvents().at(-1)?.seq ?? 0 + const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: boundary })) + expect(response.ok ? undefined : response.error).toBeUndefined() + if (!response.ok) return + const child = ctx.sessions.get(response.value.sessionId) + expect(child?.snapshotEvents().map(event => event.type)).toEqual([ + 'turn/start', 'user/message', 'turn/end', + 'turn/start', 'user/message', 'session/end-seed', 'turn/end', + ]) + const closer = child?.snapshotEvents().at(-1) + expect(closer?.type === 'turn/end' && closer.data.reason).toEqual({ kind: 'forked' }) + expect(child?.inheritedEventCount).toBe(boundary + 1) + expect(source.snapshotEvents().at(-1)?.type).toBe('user/message') + await ctx.fiber.dispose() + }) + + it('does not extend an explicit boundary through standalone tail events', async () => { + const ctx = await composed() + const source = await liveAgent(ctx, 'session-exact', 1) + const boundary = source.snapshotEvents().at(-1)?.seq ?? 0 + source.append('session/title', { title: 'after boundary', messageSeqs: [], source: { kind: 'fallback' } }) + + const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: boundary })) + + expect(response.ok ? undefined : response.error).toBeUndefined() if (!response.ok) return expect(ctx.sessions.get(response.value.sessionId)?.snapshotEvents().map(event => event.type)).toEqual([ - 'turn/start', 'user/message', 'turn/end', - 'turn/start', 'user/message', 'turn/end', - 'session/end-seed', + 'turn/start', 'user/message', 'turn/end', 'session/end-seed', ]) await ctx.fiber.dispose() }) - it('rejects an in-log anchor whose turn is still open', async () => { + it('repairs a cold open-step cut without resuming its Agent', async () => { const ctx = await composed() - const source = await liveAgent(ctx, 'session-open', 1, 'open') - const anchor = source.snapshotEvents().at(-1)?.seq ?? 0 - const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: anchor })) - expect(response).toMatchObject({ - ok: false, - error: { code: 'session/fork-unavailable', details: { sessionId: source.id } }, + const sourceId = sid('session-cold-mid-turn') + const callId = ToolCallId('cold-dangling') + const header: SessionHeader = { version: SESSION_FORMAT_VERSION, id: sourceId, createdAt: 1, cwd: '/proj', isSeeded: false } + const events = [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'step/start', seq: 1, time: 2, data: { turn: 1, step: 1 } }, + { + type: 'user/message', + seq: 2, + time: 3, + data: createUserMessage({ content: [{ type: 'text', text: 'work' }], source: { kind: 'user' } }), + surfaceOp: 'append', + }, + { + type: 'assistant/message', + seq: 3, + time: 4, + data: { + stream: [], + turn: 1, + step: 1, + message: createMessage({ + role: 'assistant', + content: [{ type: 'tool-call', id: callId, name: 'read', arguments: '{}' }], + source: { kind: 'model', provider: 'mock', model: 'mock' }, + }), + }, + surfaceOp: 'append', + }, + { type: 'tool/call', seq: 4, time: 5, data: { turn: 1, step: 1, callId, name: 'read', arguments: '{}' } }, + { type: 'step/end', seq: 5, time: 6, data: { turn: 1, step: 1 } }, + { + type: 'turn/end', + seq: 6, + time: 7, + data: { turn: 1, reason: { kind: 'error', error: { message: 'scheduler failed', code: 'UNKNOWN' } } }, + }, + ] as SessionEvent[] + ctx.provide('sessionPersistence', testSessionPersistence(ctx, { + list: () => Promise.resolve([header]), + inspect: () => Promise.resolve({ meta: header, events }), + }) as never) + const resume = vi.spyOn(ctx.agents, 'resume') + + const response = await remote(ctx).fork(request({ sessionId: sourceId, atSeq: 4 })) + + expect(response.ok ? undefined : response.error).toBeUndefined() + if (!response.ok) return + expect(resume).not.toHaveBeenCalled() + const child = ctx.sessions.get(response.value.sessionId) + expect(child?.snapshotEvents().map(event => event.type)).toEqual([ + 'turn/start', 'step/start', 'user/message', 'assistant/message', + 'tool/call', 'session/end-seed', 'tool/result', 'step/end', 'turn/end', + ]) + expect(child?.inheritedEventCount).toBe(5) + expect(child?.snapshotEvents().at(-3)).toMatchObject({ + type: 'tool/result', + data: { + turn: 1, + step: 1, + message: { source: { callId } }, + error: { code: TOOL_OUTCOME_UNKNOWN }, + }, + sourceEventSeqs: [4], }) - if (!response.ok) expect(response.error.message).toMatch(/has not completed/) + const closer = child?.snapshotEvents().at(-1) + expect(closer?.type === 'turn/end' && closer.data.reason).toEqual({ kind: 'forked' }) + expect(child?.deriveMessages().at(-1)).toMatchObject({ source: { kind: 'tool', callId } }) await ctx.fiber.dispose() }) @@ -343,7 +511,7 @@ describe('sessions.fork', () => { }) source.append('turn/end', { turn: 2, reason: { kind: 'completed' } }) const response = await remote(ctx).fork(request({ sessionId: source.id, atSeq: boundary.seq })) - expect(response.ok).toBe(true) + expect(response.ok ? undefined : response.error).toBeUndefined() if (!response.ok) return const child = ctx.agents.get(response.value.sessionId) if (child === undefined) throw new Error('fork did not publish the child agent') diff --git a/packages/api/session-controller/tests/session-history-journal.host.spec.ts b/packages/api/session-controller/tests/session-history-journal.host.spec.ts index b8bed4b26a..d836aa9734 100644 --- a/packages/api/session-controller/tests/session-history-journal.host.spec.ts +++ b/packages/api/session-controller/tests/session-history-journal.host.spec.ts @@ -5,11 +5,18 @@ import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { type Agent, type AssistantStreamFrame } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' import { LlmAttemptId, ToolCallId, createMessage, createToolResultMessage, createUserMessage } from '@deepseek-ai/dsh-llm' +import type { MessageSource } from '@deepseek-ai/dsh-llm' import type { Session, SessionEvent, SessionId } from '@deepseek-ai/dsh-session' import { SessionHistoryController } from '@deepseek-ai/dsh-api-session-controller/src/history.ts' import type { SessionFollowFrame, SessionPage, SessionWireEvent } from '@deepseek-ai/dsh-api-session-controller/types' import { createSessionTestRemote, installSessionReadTestServices } from './test-remote.ts' +type CheckpointSource = Extract + +/** Build a typed checkpoint source for a journal fixture without owning compaction. */ +function checkpointSource(compactionId: string): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: compactionId as CheckpointSource['compactionId'] } +} /** Append a production-shaped human prompt to the session surface. */ function appendUserText(session: Session, text: string): SessionEvent { return session.append('user/message', createUserMessage({ @@ -768,7 +775,7 @@ describe('Session history raw journal', () => { }) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource('journal-compaction'), }), { surfaceOp: { op: 'replace', startSeq: shadowedStart, endSeq: shadowedEnd }, sourceEventSeqs: [...shadowed, summary.seq], diff --git a/packages/api/session-controller/tests/session-models.host.spec.ts b/packages/api/session-controller/tests/session-models.host.spec.ts index bb9e77b4e2..51133aafde 100644 --- a/packages/api/session-controller/tests/session-models.host.spec.ts +++ b/packages/api/session-controller/tests/session-models.host.spec.ts @@ -298,7 +298,7 @@ describe('Web session model selection', () => { }))).selected).toEqual({ provider: 'text-only', model: 'plain' }) agent.session.append('user/message', { - id: 'summary', role: 'user', source: { kind: 'plugin', plugin: 'compact' }, + id: 'summary', role: 'user', source: { kind: 'compact-checkpoint', compactionId: 'model-selection-compaction' }, content: [{ type: 'text', text: 'image summarized' }], } as never, { surfaceOp: { op: 'replace', startSeq: imageEvent.seq, endSeq: imageEvent.seq }, diff --git a/packages/api/session-controller/tests/sessions-service.client.spec.ts b/packages/api/session-controller/tests/sessions-service.client.spec.ts index ee3298fbf8..fa0d65f857 100644 --- a/packages/api/session-controller/tests/sessions-service.client.spec.ts +++ b/packages/api/session-controller/tests/sessions-service.client.spec.ts @@ -59,12 +59,12 @@ type FeedRow = { origin?: 'subagent' running?: boolean blank?: boolean - projections?: Record + projections?: import('../src/types.ts').SessionProjectionValues } async function feedList(b: Bench, rows: FeedRow[]): Promise { b.mock.remote.session.list.mockResolvedValue(ok({ - items: rows.map(r => ({ + items: rows.map(r => ({ agentAvailable: true, sessionId: sid(r.id), updatedAt: 1, running: r.running ?? false, blank: r.blank ?? false, ...(r.cwd !== undefined ? { cwd: r.cwd } : {}), ...(r.parentId !== undefined ? { parentSessionId: sid(r.parentId) } : {}), @@ -73,7 +73,7 @@ async function feedList(b: Bench, rows: FeedRow[]): Promise { ? {} : { projections: { asOfSeq: 0, values: r.projections } }), })), - }) as never) + })) await b.svc.refresh() await Promise.resolve() // manager notifier flush } @@ -113,7 +113,7 @@ describe('list store projection', () => { it('reflects live increments (host stream via manager) into the store', async ({ bench }) => { const b = bench() await feedList(b, [{ id: 's1' }]) - b.svc.handleSessionAdded({ + b.svc.handleSessionAdded({ agentAvailable: true, sessionId: sid('s2'), updatedAt: 2, running: false, blank: true, }) await Promise.resolve() @@ -146,6 +146,24 @@ describe('search', () => { }) describe('scope tree', () => { + it('opens a conversation from follow projections without a second projection request', async ({ bench }) => { + const b = bench() + b.mock.stream(FOLLOW, followScript(ok({ + records: [], hasMore: false, + projections: { asOfSeq: 0, values: { subagentCatalog: [{ + id: sid('child'), createdAt: 1, mode: 'one-shot', + }] } }, + }))) + await feedList(b, [{ id: 's1' }]) + using reference = b.svc.retain(sid('s1'), { source: 'controllerOperation' }) + await reference.ready + await vi.waitFor(() => { + expect(b.svc.list.getSnapshot().projectionsBySession[sid('s1')]?.values.subagentCatalog) + .toEqual([{ id: sid('child'), createdAt: 1, mode: 'one-shot' }]) + }) + expect(b.mock.remote.session.projections).not.toHaveBeenCalled() + }) + it('publishes transient Assistant chunks and the named durable v2 settlement through one event source', async ({ bench }) => { const b = bench() await feedList(b, [{ id: 's1' }]) @@ -507,7 +525,7 @@ describe('Agent scope disposal lifecycle', () => { const b = bench() const readiness = b.ctx.plugin(() => undefined) await readiness - b.svc.handleSessionAdded({ + b.svc.handleSessionAdded({ agentAvailable: true, sessionId: sid('live'), updatedAt: 1, running: false, blank: true, }) await Promise.resolve() @@ -701,55 +719,70 @@ describe('borrow-only bindings', () => { }) describe('catalog-addressed navigation', () => { - it('opens an explicit catalog without retaining it and keeps one-shot labels optional', async ({ bench }) => { + it('retains a projected child independently of its parent and shares its history generation', async ({ bench }) => { const b = bench() - b.svc.handleControlFrame({ - type: 'projection', sessionId: sid('one-shot'), key: 'title', value: 'Investigate startup', seq: 2, - }) - b.mock.remote.subagents.list.mockResolvedValue(ok({ - entries: [ - { kind: 'child', id: sid('one-shot'), mode: 'one-shot', activity: 'inactive', hasChildren: false }, - { kind: 'diagnostic', id: sid('missing'), reason: 'unavailable' }, - ], - parentAvailable: true, + await feedList(b, [{ id: 'root' }]) + b.mock.remote.session.projections.mockResolvedValue(ok({ + asOfSeq: 0, values: { subagentCatalog: [{ id: sid('child'), createdAt: 1, mode: 'continuable', label: 'Child' }] }, })) - b.svc.setSubagentCatalogOpen(sid('root'), true) - await b.svc.refreshSubagents(sid('root')) - b.svc.setSubagentCatalogOpen(sid('root'), false) - - expect(b.svc.list.getSnapshot().byId[sid('one-shot')]).toMatchObject({ - title: 'Investigate startup', - displayTitle: 'Investigate startup', - projectionValues: { title: 'Investigate startup' }, - }) - expect(b.svc.list.getSnapshot().byId[sid('missing')]).toBeUndefined() - expect(b.svc.binding(sid('one-shot'))).toBeUndefined() - expect(b.mock.remote.subagents.list).toHaveBeenCalledOnce() + await b.svc.refreshProjections(sid('root')) + const address = b.svc.subagentAddress(sid('child'))! + using first = b.svc.retain(sid('child'), { source: 'controllerOperation' }) + using second = b.svc.retain(address, { source: 'gateway' }) + await Promise.all([first.ready, second.ready]) + expect(first.binding).toBe(second.binding) + expect(b.svc.scope(sid('root'))).toBeUndefined() + expect(b.svc.list.getSnapshot().ids).toEqual([sid('root')]) + expect(b.svc.list.getSnapshot().byId[sid('child')]?.retainedBy) + .toEqual({ controllerOperation: 1, gateway: 1 }) + const binding = first.binding + first.release() + expect(b.svc.binding(sid('child'))).toBe(binding) + expect(b.svc.list.getSnapshot().byId[sid('child')]?.retainedBy).toEqual({ gateway: 1 }) + second.release() + expect(b.svc.binding(sid('child'))).toBeUndefined() + expect(b.svc.list.getSnapshot().byId[sid('child')]?.retainedBy).toEqual({}) + expect(b.svc.subagentAddress(sid('child'))).toEqual(address) + expect(b.mock.log.requests(FOLLOW)).toHaveLength(1) + expect(b.mock.remote.session.projections).toHaveBeenCalledOnce() }) + for (const title of [undefined, 'Investigate startup']) { + it(`loads an unretained one-shot child with projected title ${String(title)}`, async ({ bench }) => { + const b = bench() + if (title !== undefined) b.svc.handleControlFrame({ + type: 'projection', sessionId: sid('one-shot'), key: 'title', value: title, seq: 2, + }) + b.mock.remote.session.projections.mockResolvedValue(ok({ + asOfSeq: 0, values: { subagentCatalog: [{ id: sid('one-shot'), createdAt: 1, mode: 'one-shot' }] }, + })) + await b.svc.refreshProjections(sid('root')) + expect(b.svc.list.getSnapshot().byId[sid('one-shot')]?.displayTitle).toBe(title ?? 'one-shot') + if (title !== undefined) expect(b.svc.list.getSnapshot().byId[sid('one-shot')]).toMatchObject({ + title, projectionValues: { title }, + }) + expect(b.svc.binding(sid('one-shot'))).toBeUndefined() + expect(b.svc.retainInfo(sid('one-shot')).getSnapshot().referenceCount).toBe(0) + expect(b.mock.remote.session.projections).toHaveBeenCalledOnce() + expect(b.mock.log.requests(FOLLOW)).toHaveLength(0) + }) + } + it('keeps projected titles in standard list rows for an addressed route', async ({ bench }) => { const b = bench() - b.mock.remote.subagents.list.mockImplementation((payload) => { - const parentSessionId = payload - if (parentSessionId === sid('root')) { - return Promise.resolve(ok({ - entries: [{ - kind: 'child', id: sid('child'), mode: 'continuable', label: 'Child', - activity: 'inactive', hasChildren: true, - }] as never[], - parentAvailable: true, - })) + b.mock.remote.session.projections.mockImplementation((payload) => { + const { sessionId } = payload as { sessionId: SessionId } + if (sessionId === sid('root')) { + return Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, + id: sid('child'), mode: 'continuable', label: 'Child', + }] } })) } - if (parentSessionId === sid('child')) { - return Promise.resolve(ok({ - entries: [{ - kind: 'child', id: sid('grandchild'), mode: 'continuable', label: 'Grandchild', - activity: 'inactive', hasChildren: false, - }] as never[], - parentAvailable: false, - })) + if (sessionId === sid('child')) { + return Promise.resolve(ok({ asOfSeq: 0, values: { title: 'Child session title', subagentCatalog: [{ createdAt: 1, + id: sid('grandchild'), mode: 'continuable', label: 'Grandchild', + }] } })) } - return Promise.resolve(ok({ entries: [], parentAvailable: false })) + return Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [] } })) }) await feedList(b, [ { id: 'root' }, @@ -759,8 +792,8 @@ describe('catalog-addressed navigation', () => { }, { id: 'grandchild', cwd: '/summary-grandchild', parentId: 'child', origin: 'subagent' }, ]) - await b.svc.refreshSubagents(sid('root')) - await b.svc.refreshSubagents(sid('child')) + await b.svc.refreshProjections(sid('root')) + await b.svc.refreshProjections(sid('child')) using _reference = b.svc.retain({ parentSessionId: sid('child'), childSessionId: sid('grandchild'), mode: 'continuable', }, { source: 'controllerOperation' }) @@ -776,31 +809,23 @@ describe('catalog-addressed navigation', () => { it('projects a retained descendant and discovers ancestor addresses without retaining ancestor scopes', async ({ bench }) => { const b = bench() - b.mock.remote.subagents.list.mockImplementation((payload) => { - const parentSessionId = payload - if (parentSessionId === sid('root')) { - return Promise.resolve(ok({ - entries: [{ - kind: 'child', id: sid('child'), mode: 'continuable', label: 'Child', - activity: 'inactive', hasChildren: true, - }] as never[], - parentAvailable: true, - })) + b.mock.remote.session.projections.mockImplementation((payload) => { + const { sessionId } = payload as { sessionId: SessionId } + if (sessionId === sid('root')) { + return Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, + id: sid('child'), mode: 'continuable', label: 'Child', + }] } })) } - if (parentSessionId === sid('child')) { - return Promise.resolve(ok({ - entries: [{ - kind: 'child', id: sid('grandchild'), mode: 'continuable', label: 'Grandchild', - activity: 'inactive', hasChildren: false, - }] as never[], - parentAvailable: false, - })) + if (sessionId === sid('child')) { + return Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [{ createdAt: 1, + id: sid('grandchild'), mode: 'continuable', label: 'Grandchild', + }] } })) } - return Promise.resolve(ok({ entries: [], parentAvailable: false })) + return Promise.resolve(ok({ asOfSeq: 0, values: { subagentCatalog: [] } })) }) await feedList(b, [{ id: 'root' }]) - await b.svc.refreshSubagents(sid('root')) - await b.svc.refreshSubagents(sid('child')) + await b.svc.refreshProjections(sid('root')) + await b.svc.refreshProjections(sid('child')) using reference = b.svc.retain({ parentSessionId: sid('child'), childSessionId: sid('grandchild'), mode: 'continuable', }, { source: 'controllerOperation' }) @@ -812,7 +837,9 @@ describe('catalog-addressed navigation', () => { expect(list.byId[sid('grandchild')]).toMatchObject({ parentId: sid('child'), origin: 'subagent' }) expect(b.svc.binding(sid('child'))).toBeUndefined() expect(b.svc.subagentAddress(sid('child'))).toEqual({ - parentSessionId: sid('root'), childSessionId: sid('child'), mode: 'continuable', + parentSessionId: sid('root'), + childSessionId: sid('child'), + mode: 'continuable', }) using child = b.svc.retain(sid('child'), { source: 'controllerOperation' }) await child.ready @@ -915,13 +942,12 @@ describe('fork', () => { }) }) - it('floors a fractional anchor to the real event seq the wire accepts', async ({ bench }) => { + it('sends the exact boundary seq verbatim: callers pass real event seqs', async ({ bench }) => { const b = bench() await feedList(b, [{ id: 'source', cwd: '/work' }]) b.mock.remote.session.fork.mockResolvedValue(ok({ sessionId: sid('child') })) - // The frozen node of an interrupted turn carries turnEnd.seq - 0.9. - await expect(b.svc.fork({ sessionId: sid('source'), atSeq: 41.1 })).resolves.toBe('child') + await expect(b.svc.fork({ sessionId: sid('source'), atSeq: 41 })).resolves.toBe('child') expect(b.mock.remote.session.fork).toHaveBeenCalledExactlyOnceWith({ sessionId: 'source', atSeq: 41 }) }) @@ -958,7 +984,7 @@ describe('fork', () => { describe('catalog arrival', () => { it('keeps a retained generation indexed after its Host row is removed', async ({ bench }) => { const b = bench() - b.svc.handleSessionAdded({ sessionId: sid('s-new'), updatedAt: 1, running: false, blank: true }) + b.svc.handleSessionAdded({ agentAvailable: true, sessionId: sid('s-new'), updatedAt: 1, running: false, blank: true }) await Promise.resolve() expect(b.svc.binding(sid('s-new'))).toBeUndefined() const reference = b.svc.retain(sid('s-new'), { source: 'controllerOperation' }) @@ -1027,7 +1053,7 @@ describe('blank mirror', () => { it('takes session-added blank=true as the hidden birth and list blank as reconnect authority', async ({ bench }) => { const b = bench() await feedList(b, []) - b.svc.handleSessionAdded({ + b.svc.handleSessionAdded({ agentAvailable: true, sessionId: sid('s-new'), updatedAt: 2, running: false, blank: true, cwd: '/w/a', }) await Promise.resolve() diff --git a/packages/api/session-controller/tests/subagent-catalog.host.spec.ts b/packages/api/session-controller/tests/subagent-catalog.host.spec.ts new file mode 100644 index 0000000000..3c8cf0ca00 --- /dev/null +++ b/packages/api/session-controller/tests/subagent-catalog.host.spec.ts @@ -0,0 +1,216 @@ +import { Context } from '@deepseek-ai/cordis' +import AgentRegistry from '@deepseek-ai/dsh-agent' +import type { Agent } from '@deepseek-ai/dsh-agent' +import SessionStore, { SESSION_FORMAT_VERSION, SessionLogOffset, SessionSeq, SessionId } from '@deepseek-ai/dsh-session' +import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' +import { SessionQueryError } from '@deepseek-ai/dsh-session-query' +import type { SessionObservation } from '@deepseek-ai/dsh-session-query' +import SubagentRuntime from '@deepseek-ai/dsh-subagent' +import { describe, expect, it, vi } from 'vitest' +import { + createSessionTestController, + installSessionReadTestServices, + testSessionPersistence, +} from './test-remote.ts' + +const defaults = { + defaultModelSelection: () => ({ provider: 'fixture', model: 'fixture-model' }), + cwd: '/tmp', +} + +const PARENT = SessionId('catalog-parent') +const CHILD = SessionId('catalog-child') +const header: SessionHeader = { + version: SESSION_FORMAT_VERSION, + id: PARENT, + createdAt: 1, + isSeeded: false, + cwd: '/workspace', +} +const events: SessionEvent[] = [{ + type: 'subagent/catalog', + seq: SessionSeq(0), + time: 1, + data: { + version: 0, + childId: CHILD, + childCreatedAt: 2, + mode: 'continuable', + label: 'worker', + }, +}] + +async function bench() { + const ctx = new Context() + await ctx.plugin(SessionStore) + await ctx.plugin(AgentRegistry) + ctx.provide('sessionPersistence', testSessionPersistence(ctx, { + list: () => Promise.resolve([header]), + inspect: (sessionId: SessionId) => Promise.resolve( + sessionId === PARENT ? { meta: header, events } : undefined, + ), + }) as never) + installSessionReadTestServices(ctx) + await ctx.plugin(SubagentRuntime) + const controller = createSessionTestController(ctx, defaults) + return { ctx, controller } +} + +describe('SessionController subagent catalog', () => { + it('pushes complete catalog values through the shared control stream', async () => { + const { ctx, controller } = await bench() + const signal = new AbortController() + const stream = controller.control(signal.signal)[Symbol.asyncIterator]() + try { + await stream.next() + const parent = ctx.sessions.create(PARENT, { meta: { createdAt: 7, cwd: '/workspace' } }) + parent.append('subagent/catalog', { + version: 0, childId: CHILD, childCreatedAt: 8, mode: 'continuable', label: 'worker', + }) + let frame = await stream.next() + while (!frame.done && !(frame.value.type === 'projection' && frame.value.key === 'subagentCatalog' + && Array.isArray(frame.value.value) && frame.value.value.length === 1)) { + frame = await stream.next() + } + expect(frame.value).toMatchObject({ type: 'projection', sessionId: PARENT, key: 'subagentCatalog', + value: [{ id: CHILD, createdAt: 8, mode: 'continuable', label: 'worker' }] }) + } finally { + signal.abort() + await stream.return?.() + } + }) + + it('requests a stored parent catalog by id without loading an Agent', async () => { + const { ctx, controller } = await bench() + const observe = vi.spyOn(ctx.sessionQuery, 'observeSession') + const signal = new AbortController().signal + + await expect(controller.projections({ sessionId: PARENT }, signal)).resolves.toMatchObject({ values: { subagentCatalog: [{ + id: CHILD, + mode: 'continuable', + label: 'worker', + }] } }) + expect(observe).toHaveBeenCalledOnce() + expect(observe).toHaveBeenCalledWith(PARENT, { + signal, + }) + }) + + it('serves a live parent from its maintained registry state without folding its log', async () => { + const { ctx, controller } = await bench() + const parent = ctx.sessions.create(PARENT, { meta: { createdAt: 7, cwd: '/workspace' } }) + parent.append('turn/start', { turn: 1 }) + parent.append('subagent/catalog', { + version: 0, + childId: CHILD, + childCreatedAt: 8, + mode: 'one-shot', + label: 'live worker', + }) + const snapshot = vi.spyOn(ctx.sessionProjections, 'snapshot') + const hydrate = vi.spyOn(ctx.sessionProjections, 'hydrate') + + const result = await controller.projections({ sessionId: PARENT }, new AbortController().signal) + expect(result).toMatchObject({ values: { subagentCatalog: [{ + id: CHILD, + mode: 'one-shot', + label: 'live worker', + }] } }) + expect(snapshot).toHaveBeenCalledWith(parent) + expect(hydrate).not.toHaveBeenCalled() + }) + + it('reports Agent availability through Session summaries independently of projections', async () => { + const { ctx, controller } = await bench() + const parent = ctx.sessions.create(PARENT, { meta: { createdAt: 1, cwd: '/workspace' } }) + parent.append('subagent/catalog', { + version: 0, childId: CHILD, childCreatedAt: 8, mode: 'one-shot', + }) + const summaries: boolean[] = [] + ctx.on('api-session/added', (summary) => { summaries.push(summary.agentAvailable) }) + const dispose = ctx.agents.register({ id: PARENT, session: parent, status: 'idle', ctx } as Agent) + await dispose + expect(summaries).toEqual([true]) + const available = await controller.list({}, new AbortController().signal) + expect(available.items.find(item => item.sessionId === PARENT)?.agentAvailable).toBe(true) + await dispose() + expect(summaries).toEqual([true, false]) + const unavailable = await controller.list({}, new AbortController().signal) + expect(unavailable.items.find(item => item.sessionId === PARENT)?.agentAvailable).toBe(false) + const result = await controller.projections({ sessionId: PARENT }, new AbortController().signal) + expect(result).toMatchObject({ asOfSeq: 0, values: { subagentCatalog: [{ id: CHILD, createdAt: 8, mode: 'one-shot' }] } }) + }) + + it('does not republish a Session when its Agent outlives the Session registration', async () => { + const { ctx } = await bench() + const session = ctx.sessions.prepare(SessionId('detached'), { meta: { cwd: '/workspace' } }) + const detach = ctx.sessions.enter(session) + const disposeAgent = ctx.agents.register({ id: session.id, session, status: 'idle', ctx } as Agent) + await disposeAgent + const added = vi.fn() + ctx.on('api-session/added', added) + detach() + await disposeAgent() + expect(added).not.toHaveBeenCalled() + }) + + it('reads registered projections without a subagent provider or catalog key', async () => { + const ctx = new Context() + await ctx.plugin(SessionStore) + await ctx.plugin(AgentRegistry) + installSessionReadTestServices(ctx) + const controller = createSessionTestController(ctx, defaults) + const session = ctx.sessions.create(PARENT, { meta: { cwd: '/workspace' } }) + const expected = ctx.sessionProjections.snapshot(session) + expect(expected.values.subagentCatalog).toBeUndefined() + await expect(controller.projections({ sessionId: PARENT }, new AbortController().signal)).resolves.toEqual(expected) + expect(ctx.agents.get(PARENT)).toBeUndefined() + }) + + it('validates the parent id and keeps not-found distinct from cancellation', async () => { + const { controller } = await bench() + const signal = new AbortController().signal + await expect(controller.projections({ sessionId: SessionId('') }, signal)).rejects.toMatchObject({ + code: 'gateway/bad-request', + }) + await expect(controller.projections({ sessionId: SessionId('missing') }, signal)).resolves.toEqual(null) + const aborted = new AbortController() + aborted.abort() + await expect(controller.projections({ sessionId: PARENT }, aborted.signal)).rejects.toMatchObject({ + code: 'gateway/cancelled', + }) + }) + + it('maps query cancellation, missing projections, and unexpected failures', async () => { + const { ctx, controller } = await bench() + const observe = vi.spyOn(ctx.sessionQuery, 'observeSession') + observe.mockRejectedValueOnce(new SessionQueryError( + 'query cancelled', + 'SESSION_QUERY_ABORTED', + )) + await expect(controller.projections({ sessionId: PARENT }, new AbortController().signal)).rejects.toMatchObject({ + code: 'gateway/cancelled', + }) + + observe.mockRestore() + // An observation without the catalog state means no registry served it. + const stateless: SessionObservation = { + source: 'prepared', + header, + inheritedEventCount: SessionLogOffset(0), + events, + cursor: SessionSeq(0), + retain: () => stateless, + [Symbol.dispose]: () => {}, + } + vi.spyOn(ctx.sessionQuery, 'observeSession').mockResolvedValueOnce(stateless) + await expect(controller.projections({ sessionId: PARENT }, new AbortController().signal)).rejects.toMatchObject({ + code: 'session/projections-unavailable', + }) + + vi.spyOn(ctx.sessionQuery, 'observeSession').mockRejectedValueOnce(new Error('storage offline')) + await expect(controller.projections({ sessionId: PARENT }, new AbortController().signal)).rejects.toMatchObject({ + code: 'gateway/internal', + }) + }) +}) diff --git a/packages/api/session-controller/tests/test-remote.ts b/packages/api/session-controller/tests/test-remote.ts index 721288f7dc..b4d3db8198 100644 --- a/packages/api/session-controller/tests/test-remote.ts +++ b/packages/api/session-controller/tests/test-remote.ts @@ -9,6 +9,7 @@ import type { ImageAttachmentLimits, } from '@deepseek-ai/dsh-attachment' import type { SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' +import type { SessionProjectionsValue } from '../src/types.ts' import { SessionPersistenceNotFoundError, SessionPersistenceRevision, @@ -57,6 +58,7 @@ import type { SessionSearchValue, SessionSelectModelRequest, SessionSelectModelValue, + SessionProjectionsRequest, SessionUpdateQueueRequest, SessionUpdateQueueValue, } from '../src/types.ts' @@ -80,6 +82,7 @@ export interface TestSessionRemote { signal?: AbortSignal, ): Promise> page(request: SessionPageRequest, signal?: AbortSignal): Promise> + projections(request: SessionProjectionsRequest, signal?: AbortSignal): Promise> follow(request: SessionFollowRequest, signal?: AbortSignal): AsyncIterable control(signal?: AbortSignal): AsyncIterable } @@ -360,6 +363,10 @@ export function createSessionTestRemote( () => direct.page(request, signal), signal, ), + projections: (request, signal = new AbortController().signal) => remoteResult( + () => direct.projections(request, signal), + signal, + ), follow: (request, signal = new AbortController().signal) => direct.follow(request, signal), control: (signal = new AbortController().signal) => direct.control(signal), } diff --git a/packages/api/session-controller/tests/transport.client.spec.ts b/packages/api/session-controller/tests/transport.client.spec.ts index e83dac78fd..ece1a9ff99 100644 --- a/packages/api/session-controller/tests/transport.client.spec.ts +++ b/packages/api/session-controller/tests/transport.client.spec.ts @@ -81,7 +81,6 @@ function sessionClient(remote: SessionTransportRemote): SessionRemotes { ), commands: { execute: () => Promise.reject(new Error('stream tests never run commands')) }, subagents: { - list: () => Promise.reject(new Error('stream tests never read the subagent catalog')), prompt: () => Promise.reject(new Error('stream tests never prompt a subagent')), interruptByParent: () => Promise.reject(new Error('stream tests never interrupt a subagent')), }, @@ -195,7 +194,7 @@ const invalidWireEvents: [string, unknown][] = [ ...[false, undefined].map((isError): [string, unknown] => [ `contradictory tool error ${String(isError)}`, { ...surfaceEvent('tool/result'), data: { - message: { content: [{ type: 'tool-result', content: [], ...(isError === undefined ? {} : { isError }) }] }, + message: { role: 'tool', content: [], ...(isError === undefined ? {} : { isError }) }, error: { name: 'Error', code: 'FAILURE' }, } }, ]), @@ -243,11 +242,11 @@ describe('Session Client stream adapters', () => { { ...surfaceEvent(), surfaceOp: { op: 'replace', startSeq: 2, endSeq: 0 }, sourceEventSeqs: [2, 0] }, { ...surfaceEvent('assistant/message'), data: { turn: 1, step: 1, message: {}, stream: [] } }, { ...surfaceEvent('tool/result'), data: { - message: { content: [{ type: 'tool-result', content: [], isError: true }] }, + message: { role: 'tool', content: [], isError: true }, error: { name: 'Error', code: 'FAILURE' }, meta: { extension: ['retained'] }, } }, { ...surfaceEvent('tool/result'), sourceEventSeqs: [0], data: { - message: { content: [{ type: 'tool-result', content: [], isError: true }] }, + message: { role: 'tool', content: [], isError: true }, } }, { type: 'request/header', seq: 10, time: 10, data: { reason: 'initial', header: { config: { provider: 'mock', model: 'mock' } }, diff --git a/packages/api/session-controller/tests/transport.host.spec.ts b/packages/api/session-controller/tests/transport.host.spec.ts index bac8a541d4..04b43972e9 100644 --- a/packages/api/session-controller/tests/transport.host.spec.ts +++ b/packages/api/session-controller/tests/transport.host.spec.ts @@ -441,7 +441,12 @@ describe('SessionHistoryController', () => { const signal = new AbortController().signal await expect(transport.page({ - address: { kind: 'subagent', parentSessionId, childSessionId, mode: 'continuable' }, + address: { + kind: 'subagent', + parentSessionId, + childSessionId, + mode: 'continuable', + }, throughSeq: 0, }, signal)).resolves.toMatchObject({ records: [{ type: 'event', event: { type: 'subagent/descriptor' } }], @@ -456,7 +461,12 @@ describe('SessionHistoryController', () => { throughSeq: 0, }, signal)).rejects.toMatchObject({ code: 'subagent/unauthorized' }) await expect(transport.page({ - address: { kind: 'subagent', parentSessionId, childSessionId, mode: 'one-shot' }, + address: { + kind: 'subagent', + parentSessionId, + childSessionId, + mode: 'one-shot', + }, throughSeq: 0, }, signal)).rejects.toMatchObject({ code: 'subagent/unauthorized' }) await expect(transport.page({ @@ -659,7 +669,12 @@ describe('SessionHistoryController', () => { const history = new SessionHistoryController(ctx, vi.fn()) await expect(history.page({ - address: { kind: 'subagent', parentSessionId, childSessionId, mode: 'continuable' }, + address: { + kind: 'subagent', + parentSessionId, + childSessionId, + mode: 'continuable', + }, throughSeq: -1, }, signal())).rejects.toMatchObject({ code: 'subagent/catalog-diagnostic', details: { reason: 'unsupported' }, @@ -690,7 +705,12 @@ describe('SessionHistoryController', () => { })) const childSnapshot = vi.spyOn(child.ctx.sessionProjections, 'snapshot') const page = await child.transport.page({ - address: { kind: 'subagent', parentSessionId, childSessionId, mode: 'continuable' }, + address: { + kind: 'subagent', + parentSessionId, + childSessionId, + mode: 'continuable', + }, throughSeq: 0, }, signal()) expect('projections' in page).toBe(false) diff --git a/packages/bundle/headless/src/json-stream.ts b/packages/bundle/headless/src/json-stream.ts index f02583f2ad..2fa8cbc449 100644 --- a/packages/bundle/headless/src/json-stream.ts +++ b/packages/bundle/headless/src/json-stream.ts @@ -301,12 +301,12 @@ export function projectJsonRun( // Compaction replaces older results in the surface; those are history, // not this run's output, and would otherwise duplicate a callId. if (event.surfaceOp !== 'append') return - const block = event.data.message.content[0] + const message = event.data.message write({ type: 'tool_result', - callId: block.toolCallId, - status: block.isError === true ? 'error' : 'completed', - result: resultText(block.content), + callId: message.toolCallId, + status: message.isError === true ? 'error' : 'completed', + result: resultText(message.content), }) return } diff --git a/packages/bundle/headless/tests/headless.spec.ts b/packages/bundle/headless/tests/headless.spec.ts index 96f646d264..4a92ad0991 100644 --- a/packages/bundle/headless/tests/headless.spec.ts +++ b/packages/bundle/headless/tests/headless.spec.ts @@ -13,7 +13,7 @@ import type { ResumeAgentOptions, } from '@deepseek-ai/dsh-agent' import AgentDefaultModelConfig from '@deepseek-ai/dsh-agent-default-model' -import { LlmAttemptId, ToolCallId, createAssistantMessage, createToolResultMessage, type StreamChunk } from '@deepseek-ai/dsh-llm' +import { LlmAttemptId, ToolCallId, createAssistantMessage, createToolResultMessage, type MessageId, type StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import type { Session, SessionId, UserMessage } from '@deepseek-ai/dsh-session' @@ -263,8 +263,8 @@ describe('headless runner', () => { const test = await bench({ before(session) { const setupMessage = { - role: 'user', content: [{ type: 'text', text: 'setup' }], source: { kind: 'user' }, id: 'setup', - } as UserMessage + role: 'user', content: [{ type: 'text', text: 'setup' }], source: { kind: 'user' }, id: brandString('setup'), + } satisfies UserMessage appendTurn(session, 0, setupMessage, 'pre-task noise', true) }, async afterPrompt(session, message) { @@ -607,8 +607,8 @@ describe('headless runner', () => { }) const session = test.ctx.sessions.create(brandString('session-exact'), { meta: { cwd: process.cwd() } }) const history = { - role: 'user', content: [{ type: 'text', text: 'earlier' }], source: { kind: 'user' }, id: 'history', - } as UserMessage + role: 'user', content: [{ type: 'text', text: 'earlier' }], source: { kind: 'user' }, id: brandString('history'), + } satisfies UserMessage appendTurn(session, 0, history, 'earlier answer', true) const before = session.seq expect(await test.run()).toMatchObject({ code: 0, out: 'resumed answer\n', err: '' }) @@ -789,8 +789,8 @@ describe('headless runner', () => { const test = await bench({ before(session) { const history = { - role: 'user', content: [{ type: 'text', text: 'earlier' }], source: { kind: 'user' }, id: 'history', - } as UserMessage + role: 'user', content: [{ type: 'text', text: 'earlier' }], source: { kind: 'user' }, id: brandString('history'), + } satisfies UserMessage appendTurn(session, 0, history, 'earlier answer', true) selectPreset(session, 'minimal') }, @@ -845,8 +845,8 @@ describe('headless runner', () => { const test = await bench({ before(session) { const history = { - role: 'user', content: [{ type: 'text', text: 'earlier' }], source: { kind: 'user' }, id: 'history', - } as UserMessage + role: 'user', content: [{ type: 'text', text: 'earlier' }], source: { kind: 'user' }, id: brandString('history'), + } satisfies UserMessage appendTurn(session, 0, history, 'earlier answer', true) capturedLength = session.seq Object.defineProperty(session, 'eventAt', { value: () => undefined }) diff --git a/packages/bundle/headless/tests/json-stream.spec.ts b/packages/bundle/headless/tests/json-stream.spec.ts index a9332ee894..3e49a70dd5 100644 --- a/packages/bundle/headless/tests/json-stream.spec.ts +++ b/packages/bundle/headless/tests/json-stream.spec.ts @@ -59,7 +59,7 @@ function toolResult( data: { turn: 1, step: 1, - message: { content: [{ type: 'tool-result', toolCallId: callId, content, isError: false }] }, + message: { role: 'tool', toolCallId: callId, isError: false, content }, }, } as unknown as SessionEvent } @@ -169,12 +169,10 @@ describe('--json projection', () => { turn: 1, step: 1, message: { - content: [{ - type: 'tool-result', - toolCallId: 'c2', - content: [{ type: 'image' }, { type: 'text' }, { type: 'text', text: 'boom' }], - isError: true, - }], + role: 'tool', + toolCallId: 'c2', + isError: true, + content: [{ type: 'image' }, { type: 'text' }, { type: 'text', text: 'boom' }], }, }, } as unknown as SessionEvent) diff --git a/packages/client/locale/tests/language-row.client.spec.tsx b/packages/client/locale/tests/language-row.client.spec.tsx index 7c2a0ec626..5068b90218 100644 --- a/packages/client/locale/tests/language-row.client.spec.tsx +++ b/packages/client/locale/tests/language-row.client.spec.tsx @@ -20,7 +20,7 @@ const OPTIONS = [{ id: 'zh', label: '中文' }, { id: 'en', label: 'English' }] function emptySessions() { const store = createSnapshotStore( - { ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {} }) + { ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {} }) return bindSnapshotSelector(store) } function emptyWorkspaces() { diff --git a/packages/client/ui-agent-preset/README.i18n.yaml b/packages/client/ui-agent-preset/README.i18n.yaml index 1888d7c2e0..2ed6513974 100644 --- a/packages/client/ui-agent-preset/README.i18n.yaml +++ b/packages/client/ui-agent-preset/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-agent-preset/README.md -README.md: a76a265c7af54f88fc12540598d6552a74c8dc50 -README.zh.md: de66174015b383f8d0c883bc2a9e544b30621c5e +README.md: c7a87da591c1cafc433fbb3bb5fa216d94ab85ef +README.zh.md: a54b47baed132e790fc4f44ad1155f48a19c430b diff --git a/packages/client/ui-agent-preset/README.md b/packages/client/ui-agent-preset/README.md index a76a265c7a..c7a87da591 100644 --- a/packages/client/ui-agent-preset/README.md +++ b/packages/client/ui-agent-preset/README.md @@ -47,6 +47,8 @@ When the roster carries the self-referential `cordis` preset, its dashed add-car The settings section writes the Host's existing `agent-presets` namespace through `settings.update`. Its visibility switch sets only `modeSelectionEnabled`, and its make-default action writes `default` only while the picker is shown. After either write, the Host roster supplies the effective default, and the chip controller's `agentPresets/select` path carries it to the same still-blank session; that path is the only session-mutation API these surfaces use. Display options and Host-effective visibility come from `agentPresets/list` — the roster already marks the effective Host default and carries `modeSelectionEnabled`, so a non-loopback read-only client stays consistent without introspecting the settings schema. The settings section queries `settings.canOpenAgentPresetDirectory()` when it first loads and joins that result with the roster; a failed query removes only the native-open affordance. The new-session chip renders only while `modeSelectionEnabled` is true; hiding it drops a pending stage and local menu or refusal state, while the header label remains registered and reads each session's recorded preset. The stage is applied when a session arrives (covering both the session a workspace connect created and the blank one it reused) and dropped on refusal. A refusal announces itself as a transient banner over the composer column, because the chip's label has already reverted and a preset the Host refuses to mount is one discovery reported healthy — its roster card carries no reason to go back and read. Only a pick a person just made is announced; the applier that runs when a session becomes current is not. [`dsh-client-connection`](../connection/README.md) authenticates `agentPresets/read`, `agentPresets/copy`, `settings/openAgentPresetDirectory`, `agentPresets/deletePreset`, `agentPresets/list`, and every other Host API method with the same browser session. A composition still names the plugins a session runs, so reading one is reconnaissance, while copy, delete, and the settings-owned directory opener manage the roster and drive the Host desktop. The section re-reads on its own actions, `settings/document-updated`, and `connection/reset`, because composition files are edited outside the browser and nothing on the wire announces a file change. +The chip follows the preset projection of its bound Session while its plugin and Provider generation remain active. Settings synchronization creates the same bound controller when needed, even before the chip mounts. A late projection or another client's preset update refreshes the display without submitting a selection; list notifications do not repeat an in-flight selection. Settings changes wait for that selection and recheck the captured blank Session before applying. A choice staged during a pending request remains available afterward. + ----- diff --git a/packages/client/ui-agent-preset/README.zh.md b/packages/client/ui-agent-preset/README.zh.md index de66174015..a54b47baed 100644 --- a/packages/client/ui-agent-preset/README.zh.md +++ b/packages/client/ui-agent-preset/README.zh.md @@ -47,6 +47,8 @@ kind: "package-reference" 设置分区通过现有的 `settings.update` 写入宿主的 `agent-presets` 命名空间。可见性开关只设置 `modeSelectionEnabled`;仅当选择器显示时,设为默认动作才会写入 `default`。两种写入之后,都由宿主名单给出当前生效的默认值,再由 chip controller 的 `agentPresets/select` 链路把它带到同一个仍为空白的会话;这些界面只使用这一条会话修改 API。展示选项与宿主的生效可见性来自 `agentPresets/list`——名单本身已标记宿主当前生效的默认值并携带 `modeSelectionEnabled`,因此非 loopback 的只读客户端无需内省 settings schema 也能保持一致。设置分区首次加载时查询 `settings.canOpenAgentPresetDirectory()`,并把结果与名单合并;查询失败只会移除原生打开动作。新建会话 chip 仅在 `modeSelectionEnabled` 为 `true` 时渲染;隐藏它会丢弃待处理的暂存选择及本地菜单或失败横幅状态,而标题标签保持注册并读取每个会话已记录的 preset。暂存值在会话到达时应用(既覆盖工作区连接新建的会话,也覆盖它复用的空白会话),被拒绝时丢弃。系统会通过 composer 列上方的瞬时横幅提示拒绝结果,因为 chip 的标签此时已经恢复原值,而被宿主拒绝挂载的 preset 正是发现过程报告为健康的那一种——它的名单卡片上没有任何原因可供回头查看。只有用户刚做出的选择会触发提示;会话成为当前会话时触发的应用器不会。[`dsh-client-connection`](../connection/README.zh.md) 使用同一浏览器会话认证 `agentPresets/read`、`agentPresets/copy`、`settings/openAgentPresetDirectory`、`agentPresets/deletePreset`、`agentPresets/list` 及其他所有宿主 API 方法。组装仍会指明一个会话所运行的插件,因此读取属于侦察,而复制、删除与设置模块拥有的目录打开操作负责管理名单并驱动宿主桌面。分区在自身操作、`settings/document-updated` 与 `connection/reset` 时重读,因为组装文件在浏览器之外编辑,协议链路不会通知文件变动。 +只要插件及 Provider generation 仍有效,选择芯片就会跟随其绑定 Session 的预设投影。即使选择芯片尚未挂载,设置同步也会按需创建同一个绑定控制器。延后到达的投影或其他客户端的预设更新会刷新显示,而不会提交选择;列表通知不会重复仍在进行中的选择操作。设置修改会等待该操作结束,并在应用之前重新检查已捕获的空白 Session。请求期间暂存的新选择会保留。 + ----- diff --git a/packages/client/ui-agent-preset/src/client/index.ts b/packages/client/ui-agent-preset/src/client/index.ts index 1dad3aae98..c335518aff 100644 --- a/packages/client/ui-agent-preset/src/client/index.ts +++ b/packages/client/ui-agent-preset/src/client/index.ts @@ -68,22 +68,32 @@ export function apply(ctx: ClientContext): void { const controller = new AgentPresetSettingsController(ctx) const staged: AgentPresetStage = { id: undefined, introduce: false } const seats = new WeakMapWithValues() + const boundSeatDisposers = new Set<() => Promise>() + ctx.effect(() => async () => { + await Promise.all([...boundSeatDisposers].map(dispose => dispose())) + }, 'ui-agent-preset: bound selections') const unboundSeat = new AgentPresetSeatController(ctx, () => undefined, staged) - const seatFor = (scope: ClientContext, binding: SessionBinding): AgentPresetSeatController => { - let seat = seats.get(binding) - if (seat !== undefined) return seat - seat = new AgentPresetSeatController(scope, () => { - if (scope.sessions.binding(binding.sessionId) !== binding) return undefined - const summary = scope.sessions.list.getSnapshot().byId[binding.sessionId] + const seatFor = (binding: SessionBinding): AgentPresetSeatController => { + const existing = seats.get(binding) + if (existing !== undefined) return existing + const seat = new AgentPresetSeatController(ctx, () => { + if (ctx.sessions.binding(binding.sessionId) !== binding) return undefined + const summary = ctx.sessions.list.getSnapshot().byId[binding.sessionId] return summary !== undefined - && (scope.sessions.retainInfo(binding.sessionId).getSnapshot().retainedBy.mainView ?? 0) > 0 + && (ctx.sessions.retainInfo(binding.sessionId).getSnapshot().retainedBy.mainView ?? 0) > 0 ? summary : undefined }, staged) seats.set(binding, seat) - binding.ctx.effect(() => () => { - seats.delete(binding) + const dispose = binding.ctx.effect(() => { + const stop = ctx.sessions.list.subscribe(() => { void seat.apply() }) + return () => { + stop() + seats.delete(binding) + boundSeatDisposers.delete(dispose) + } }, 'ui-agent-preset: Provider binding') + boundSeatDisposers.add(dispose) return seat } const section = new AgentPresetSectionController(ctx, () => { @@ -91,14 +101,14 @@ export function apply(ctx: ClientContext): void { void unboundSeat.load() for (const seat of seats.values) void seat.load() }) - const mainBlankSeat = (scope: ClientContext): AgentPresetSeatController | undefined => { - const summary = Object.values(scope.sessions.list.getSnapshot().byId) + const mainBlankSeat = (): AgentPresetSeatController | undefined => { + const summary = Object.values(ctx.sessions.list.getSnapshot().byId) .find((session) => { /* v8 ignore next -- retained source counts omit zero-valued entries. */ return session.blank && (session.retainedBy.mainView ?? 0) > 0 }) - const binding = summary === undefined ? undefined : scope.sessions.binding(summary.id) - return binding === undefined ? undefined : seatFor(scope, binding) + const binding = summary === undefined ? undefined : ctx.sessions.binding(summary.id) + return binding === undefined ? undefined : seatFor(binding) } ctx.effect(() => ctx.locale.register('settings.agentPreset', { zh, en }), 'ui-agent-preset: settings row dictionaries') @@ -134,8 +144,8 @@ export function apply(ctx: ClientContext): void { let creatorDraft: (() => void) | undefined ctx.inject(['slots', 'conversation', 'sessions', 'uiWorkspace'], (scope: ClientContext) => { const seatInjected = (sessionId: SessionId | undefined): AgentPresetSeatInjected => { - const binding = sessionId === undefined ? undefined : scope.sessions.binding(sessionId) - const seat = binding === undefined ? unboundSeat : seatFor(scope, binding) + const binding = sessionId === undefined ? undefined : ctx.sessions.binding(sessionId) + const seat = binding === undefined ? unboundSeat : seatFor(binding) return { hooks: { agentPresetSeat: seat.store, showPresetPicker: ctx.settingsScope.developerTools.enabled }, load: () => seat.load(), @@ -152,7 +162,7 @@ export function apply(ctx: ClientContext): void { scope.effect(() => { creatorDraft = () => { if (!section.store.getSnapshot().showPicker) return - const seat = mainBlankSeat(scope) ?? unboundSeat + const seat = mainBlankSeat() ?? unboundSeat seat.stage('cordis', true) scope.uiWorkspace.startSession() void seat.apply() @@ -183,7 +193,7 @@ export function apply(ctx: ClientContext): void { const summary = Object.values(ctx.sessions.list.getSnapshot().byId) .find(session => session.blank && (session.retainedBy.mainView ?? 0) > 0) const binding = summary === undefined ? undefined : ctx.sessions.binding(summary.id) - const seat = binding === undefined ? undefined : seats.get(binding) + const seat = binding === undefined ? undefined : seatFor(binding) const sessionId = seat?.blankSessionId() return async (id: string) => { if (seat === undefined || sessionId === undefined || binding === undefined diff --git a/packages/client/ui-agent-preset/src/client/seat-store.ts b/packages/client/ui-agent-preset/src/client/seat-store.ts index ca19a56b69..45bd9373e4 100644 --- a/packages/client/ui-agent-preset/src/client/seat-store.ts +++ b/packages/client/ui-agent-preset/src/client/seat-store.ts @@ -63,6 +63,8 @@ export class AgentPresetSeatController { /** Only the newest roster read may publish after overlapping refreshes. */ private loadGeneration = 0 + /** Completion of the active Host selection; Settings choices wait before staging. */ + private pendingSelection: Promise | undefined constructor( private readonly ctx: ClientContext, @@ -78,6 +80,11 @@ export class AgentPresetSeatController { this.store.set({ ...this.store.getSnapshot(), ...patch }) } + private clearStage(): void { + this.staged.id = undefined + this.staged.introduce = false + } + /** * Read the roster and open the chip on the Host-effective default. * @returns once the snapshot reflects the host. @@ -92,8 +99,7 @@ export class AgentPresetSeatController { } const { presets, modeSelectionEnabled } = roster.value if (!modeSelectionEnabled) { - this.staged.id = undefined - this.staged.introduce = false + this.clearStage() } this.fallback = presets.find(preset => preset.isDefault)?.id ?? presets[0]?.id ?? '' const session = this.currentSession() @@ -128,8 +134,7 @@ export class AgentPresetSeatController { async select(id: string): Promise { if (this.store.getSnapshot().busy) return undefined this.stage(id) - await this.apply() - return this.store.getSnapshot().error ?? undefined + return await this.apply() } /** @@ -160,7 +165,7 @@ export class AgentPresetSeatController { /** * Apply a Settings choice only if its captured Session is still current and - * blank. The selection uses the existing stage/apply path. + * blank after any pending selection settles. The selection uses the existing stage/apply path. * @param expectedSessionId - blank Session captured before the Settings write. * @param id - the effective default that the write persisted. * @returns the Host refusal text, or undefined when applied or no longer relevant. @@ -169,11 +174,11 @@ export class AgentPresetSeatController { expectedSessionId: SessionSummary['id'], id: string, ): Promise { + while (this.pendingSelection !== undefined) await this.pendingSelection const session = this.currentSession() if (session === undefined || !session.blank || session.id !== expectedSessionId) return undefined this.stage(id) - await this.apply() - return this.store.getSnapshot().error ?? undefined + return await this.apply() } /** Acknowledge the introduction cue once the chip has played it. */ @@ -188,9 +193,11 @@ export class AgentPresetSeatController { * * Called both by `select()` and by whoever observes the current session * changing, because the session may appear either before or after the pick. - * @returns once the switch settled, or immediately when there is nothing to do. + * List updates do not repeat a selection while its response is pending. + * @returns this attempt's Host refusal, or undefined when successful or no switch starts. */ - async apply(): Promise { + async apply(): Promise { + if (this.store.getSnapshot().busy) return const staged = this.staged.id const session = this.currentSession() if (staged === undefined) { @@ -202,32 +209,37 @@ export class AgentPresetSeatController { // A started session's history was produced under its own composition; the // host refuses the swap, so the stage is no longer meaningful. if (!session.blank || presetOf(session) === staged) { - this.staged.id = undefined - this.staged.introduce = false + this.clearStage() return } - this.set({ busy: true, error: null }) - const result = await this.ctx.remote.agentPresets.select(session.id, staged) - this.staged.id = undefined - this.staged.introduce = false - if (!result.ok) { - const { error } = result - this.set({ - busy: false, - // A refusal carries its cause twice: `message` wraps it in the - // roster's own frame, which names the preset the surface reporting - // this already names, and a `reason` detail holds the same cause - // without it. Read by the detail rather than by the code, because - // every refusal that has a cause to give names it the same way. - error: 'reason' in error.details && typeof error.details.reason === 'string' + const completion = Promise.withResolvers() + this.pendingSelection = completion.promise + this.clearStage() + try { + this.set({ busy: true, error: null }) + const result = await this.ctx.remote.agentPresets.select(session.id, staged) + if (!result.ok) { + const { error } = result + const refusal = 'reason' in error.details && typeof error.details.reason === 'string' ? error.details.reason - : error.message, - current: presetOf(session) ?? '', - }) - return + : error.message + this.set({ + // A refusal carries its cause twice: `message` wraps it in the + // roster's own frame, which names the preset the surface reporting + // this already names, and a `reason` detail holds the same cause + // without it. Read by the detail rather than by the code, because + // every refusal that has a cause to give names it the same way. + error: refusal, + current: this.staged.id ?? presetOf(session) ?? '', + }) + return refusal + } + this.set({ current: this.staged.id ?? result.value }) + } finally { + this.pendingSelection = undefined + this.set({ busy: false }) + completion.resolve(undefined) } - // Consumed: the next new session opens on the Host-effective default again. - this.set({ busy: false, current: result.value }) } } diff --git a/packages/client/ui-agent-preset/tests/apply.client.spec.ts b/packages/client/ui-agent-preset/tests/apply.client.spec.ts index 123fd48b15..1e28cb44f4 100644 --- a/packages/client/ui-agent-preset/tests/apply.client.spec.ts +++ b/packages/client/ui-agent-preset/tests/apply.client.spec.ts @@ -74,6 +74,8 @@ const ROSTER_HIDDEN = { async function bench(options: { failSettingsUpdate?: boolean + selectGate?: Promise + settingsRosterGate?: Promise } = {}) { const ctx = new Context() // The host's answer, mutable so a spec can move the default the way the @@ -87,6 +89,8 @@ async function bench(options: { const calls: string[] = [] let savedDefault = 'standard' let selectionEnabled = true + let settingsSaved = false + const settingsRosterStarted = Promise.withResolvers() // The row reads `describe` to learn whether this browser may write at all, // and its default write is the one op this spec records. const settings = { @@ -112,6 +116,7 @@ async function bench(options: { ROSTER = !selectionEnabled ? ROSTER_HIDDEN : savedDefault === 'minimal' ? ROSTER_MOVED : ROSTER_ONE + settingsSaved = true return Promise.resolve({ ok: true as const, value: {} }) }, openAgentPresetDirectory: (agentPreset: string) => { @@ -126,7 +131,14 @@ async function bench(options: { // `inject`, and the property is what `ctx.remote.agentPresets` reads, // because the double is a plain provided object rather than a Service. const agentPresets = { - list: () => { calls.push('list'); return Promise.resolve(ROSTER) }, + list: () => { + calls.push('list') + if (settingsSaved) { + settingsRosterStarted.resolve(undefined) + if (options.settingsRosterGate !== undefined) return options.settingsRosterGate.then(() => ROSTER) + } + return Promise.resolve(ROSTER) + }, read: () => Promise.resolve({ ok: true as const, value: { agentPreset: 'standard', trust: 'system', content: '' }, @@ -141,13 +153,13 @@ async function bench(options: { deletePreset: () => Promise.resolve({ ok: true as const, value: undefined }), select: (_agentId: SessionId, agentPreset: string) => { calls.push(`select:${agentPreset}`) - return Promise.resolve({ ok: true as const, value: agentPreset }) + return Promise.resolve(options.selectGate).then(() => ({ ok: true as const, value: agentPreset })) }, } ctx.provide('remote.agentPresets', agentPresets as never) Object.assign(remote, { agentPresets }) await ctx.plugin({ inject: [...settingsInject], apply: settingsApply }).await() - return { ctx, slots: ctx.get('slots') as SlotRegistry, calls, moveDefault, remote } + return { ctx, slots: ctx.get('slots') as SlotRegistry, calls, moveDefault, remote, settingsRosterStarted: settingsRosterStarted.promise } } function declareRoot(slots: SlotRegistry): () => void { @@ -234,10 +246,70 @@ function sessionsDouble(ctx: Context, state: { }), /** Push a list change the way the runtime's store does. */ notify: () => { for (const fn of listeners) fn() }, + listenerCount: () => listeners.size, } } +async function settingsWithoutChip(initialPreset: string, settingsRosterGate?: Promise) { + const b = await bench(settingsRosterGate === undefined ? {} : { settingsRosterGate }) + declareRoot(b.slots) + const sessions = sessionsDouble(b.ctx, { + current: 'blank', + byId: { blank: { id: 'blank', blank: true, projectionValues: { agentPreset: initialPreset } } }, + }) + const bindingOwner = b.ctx.plugin({ apply() {} }) + await bindingOwner.await() + sessions.binding('blank')!.ctx = bindingOwner.ctx + b.ctx.provide('sessions', sessions as never) + const feature = b.ctx.plugin({ inject: [...inject], apply }) + await feature.await() + const section = (b.slots.entries('settings.section')[0]! + .inject as unknown as () => AgentPresetSectionInjected)() + await section.load() + expect(b.slots.entries('conversation.hero.agentPreset')).toHaveLength(0) + return { ...b, bindingOwner, feature, section, sessions } +} + describe('ui-agent-preset apply', () => { + const settingsActions = [ + { action: 'makeDefault', initial: 'standard', selected: 'minimal', run: (section: AgentPresetSectionInjected) => section.makeDefault('minimal') }, + { action: 'setPickerVisible', initial: 'minimal', selected: 'standard', run: (section: AgentPresetSectionInjected) => section.setPickerVisible(false) }, + ] + + it.each(settingsActions)('synchronizes $action before the chip mounts', async ({ initial, selected, run }) => { + const b = await settingsWithoutChip(initial) + try { + await run(b.section) + expect(b.calls.filter(call => call.startsWith('select:'))).toEqual([`select:${selected}`]) + expect(b.sessions.listenerCount()).toBe(1) + } finally { + await b.ctx.fiber.dispose() + } + expect(b.sessions.listenerCount()).toBe(0) + }) + + it.each(settingsActions.flatMap(action => (['feature', 'binding'] as const).map(owner => ({ ...action, owner }))))( + 'does not finish $action into a disposed $owner before the chip mounts', + async ({ initial, run, owner }) => { + const saved = Promise.withResolvers() + const b = await settingsWithoutChip(initial, saved.promise) + const operation = run(b.section) + try { + expect(b.sessions.listenerCount()).toBe(1) + await b.settingsRosterStarted + await (owner === 'feature' ? b.feature : b.bindingOwner).dispose() + expect(b.sessions.listenerCount()).toBe(0) + saved.resolve(undefined) + await operation + expect(b.calls.filter(call => call.startsWith('select:'))).toEqual([]) + } finally { + saved.resolve(undefined) + await operation + await b.ctx.fiber.dispose() + } + }, + ) + it('keeps the host Loader entry inert', () => { expect(hostApply).not.toThrow() }) @@ -473,6 +545,58 @@ describe('ui-agent-preset apply', () => { await ctx.fiber.dispose() }) + it.each(['feature', 'binding'] as const)('tracks bound preset changes until its %s owner stops', async (disposedOwner) => { + const selection = Promise.withResolvers() + const { ctx, slots, calls } = await bench({ selectGate: selection.promise }) + try { + declareRoot(slots) + declareConversation(slots) + ctx.provide('conversation', {} as never) + const state = { + current: 's1', + byId: { s1: { id: 's1', blank: true, projectionValues: {} as { agentPreset?: string } } }, + } + const sessions = sessionsDouble(ctx, state) + const bindingOwner = ctx.plugin({ apply() {} }) + await bindingOwner.await() + sessions.binding('s1')!.ctx = bindingOwner.ctx + ctx.provide('sessions', sessions as never) + ctx.provide('uiWorkspace', uiWorkspaceDouble() as never) + const feature = ctx.plugin({ inject: [...inject, 'conversation', 'sessions', 'uiWorkspace'], apply }) + await feature.await() + const seat = (slots.entries('conversation.hero.agentPreset')[0]! + .inject as unknown as (sessionId: SessionId) => AgentPresetSeatInjected)(SessionId('s1')) + await seat.load() + expect(seat.hooks.agentPresetSeat.getSnapshot().current).toBe('') + + state.byId.s1.projectionValues.agentPreset = 'standard' + sessions.notify() + expect(seat.hooks.agentPresetSeat.getSnapshot().current).toBe('standard') + state.byId.s1.projectionValues.agentPreset = 'minimal' + sessions.notify() + expect(seat.hooks.agentPresetSeat.getSnapshot().current).toBe('minimal') + expect(calls.filter(call => call.startsWith('select:'))).toEqual([]) + + const selecting = seat.select('standard') + expect(seat.hooks.agentPresetSeat.getSnapshot().busy).toBe(true) + sessions.notify() + sessions.notify() + expect(calls.filter(call => call.startsWith('select:'))).toEqual(['select:standard']) + selection.resolve(undefined) + await selecting + state.byId.s1.projectionValues.agentPreset = 'standard' + sessions.notify() + + await (disposedOwner === 'feature' ? feature : bindingOwner).dispose() + state.byId.s1.projectionValues.agentPreset = 'minimal' + sessions.notify() + expect(seat.hooks.agentPresetSeat.getSnapshot().current).toBe('standard') + } finally { + selection.resolve(undefined) + await ctx.fiber.dispose() + } + }) + it('does not sync a blank Session that is not retained by the main view', async () => { const { ctx, slots, calls } = await bench() declareRoot(slots) @@ -822,6 +946,102 @@ describe('ui-agent-preset apply', () => { }) describe('AgentPresetSeatController reconciliation', () => { + it.each([ + { refuseFirst: false, refuseLatest: false }, + { refuseFirst: false, refuseLatest: true }, + { refuseFirst: true, refuseLatest: false }, + { refuseFirst: true, refuseLatest: true }, + ])('waits for a newer Settings selection (first refused: $refuseFirst, latest refused: $refuseLatest)', async ({ refuseFirst, refuseLatest }) => { + const refusal = { ok: false as const, error: new RemoteError('gateway/internal', 'selection refused', {}) } + type Outcome = { ok: true; value: string } | typeof refusal + const requests: { preset: string; outcome: ReturnType> }[] = [] + const session = { id: SessionId('blank'), blank: true, projectionValues: { agentPreset: 'standard' } } + const controller = new AgentPresetSeatController({ + remote: { agentPresets: { select: (_id: SessionId, preset: string) => { + const outcome = Promise.withResolvers() + requests.push({ preset, outcome }) + return outcome.promise + } } }, + } as never, () => session) + const first = controller.select('minimal') + let settingsSettled = false + const settings = controller.syncBlankSession(session.id, 'cordis').finally(() => { settingsSettled = true }) + await controller.apply() + expect(requests.map(request => request.preset)).toEqual(['minimal']) + requests[0]!.outcome.resolve(refuseFirst ? refusal : { ok: true, value: 'minimal' }) + await first + expect(requests.map(request => request.preset)).toEqual(['minimal', 'cordis']) + expect(settingsSettled).toBe(false) + await controller.apply() + expect(requests).toHaveLength(2) + requests[1]!.outcome.resolve(refuseLatest ? refusal : { ok: true, value: 'cordis' }) + await expect(settings).resolves.toBe(refuseLatest ? 'selection refused' : undefined) + expect(controller.store.getSnapshot()).toMatchObject({ + current: refuseLatest ? 'standard' : 'cordis', busy: false, + error: refuseLatest ? 'selection refused' : null, + }) + }) + + it.each([false, true])('preserves a stage created while an earlier selection is pending (refused: %s)', async (refused) => { + const refusal = { ok: false as const, error: new RemoteError('gateway/internal', 'selection refused', {}) } + const firstReply = Promise.withResolvers<{ ok: true; value: string } | typeof refusal>() + const select = vi.fn((_id: SessionId, preset: string) => preset === 'minimal' + ? firstReply.promise + : Promise.resolve({ ok: true as const, value: preset })) + const controller = new AgentPresetSeatController({ remote: { agentPresets: { select } } } as never, + () => ({ id: SessionId('blank'), blank: true, projectionValues: { agentPreset: 'standard' } })) + const first = controller.select('minimal') + controller.stage('cordis', true) + await controller.apply() + expect(select).toHaveBeenCalledOnce() + firstReply.resolve(refused ? refusal : { ok: true, value: 'minimal' }) + await first + expect(controller.store.getSnapshot().current).toBe('cordis') + await controller.apply() + expect(select.mock.calls.map(call => call[1])).toEqual(['minimal', 'cordis']) + }) + + it.each([false, true])('serializes Settings choices and preserves each refusal (middle refused: %s)', async (refused) => { + const refusal = { ok: false as const, error: new RemoteError('gateway/internal', 'selection refused', {}) } + type Outcome = { ok: true; value: string } | typeof refusal + const requests: { preset: string; outcome: ReturnType> }[] = [] + const session = { id: SessionId('blank'), blank: true, projectionValues: { agentPreset: 'standard' } } + const controller = new AgentPresetSeatController({ + remote: { agentPresets: { select: (_id: SessionId, preset: string) => { + const outcome = Promise.withResolvers() + requests.push({ preset, outcome }) + return outcome.promise + } } }, + } as never, () => session) + const first = controller.select('minimal') + const second = controller.syncBlankSession(session.id, 'cordis') + const third = controller.syncBlankSession(session.id, 'coding') + expect(requests.map(request => request.preset)).toEqual(['minimal']) + requests[0]!.outcome.resolve({ ok: true, value: 'minimal' }) + await first + expect(requests.map(request => request.preset)).toEqual(['minimal', 'cordis']) + requests[1]!.outcome.resolve(refused ? refusal : { ok: true, value: 'cordis' }) + await expect(second).resolves.toBe(refused ? 'selection refused' : undefined) + expect(requests.map(request => request.preset)).toEqual(['minimal', 'cordis', 'coding']) + requests[2]!.outcome.resolve({ ok: true, value: 'coding' }) + await third + expect(controller.store.getSnapshot()).toMatchObject({ current: 'coding', busy: false }) + }) + + it('does not apply a waiting Settings choice to a replacement binding', async () => { + const reply = Promise.withResolvers<{ ok: true; value: string }>() + const select = vi.fn(() => reply.promise) + let current = { id: SessionId('first'), blank: true, projectionValues: { agentPreset: 'standard' } } + const controller = new AgentPresetSeatController({ remote: { agentPresets: { select } } } as never, () => current) + const first = controller.select('minimal') + const settings = controller.syncBlankSession(current.id, 'cordis') + current = { ...current, id: SessionId('replacement') } + reply.resolve({ ok: true, value: 'minimal' }) + await Promise.all([first, settings]) + await controller.apply() + expect(select).toHaveBeenCalledExactlyOnceWith(SessionId('first'), 'minimal') + }) + it('does not capture a non-blank Session', () => { const controller = new AgentPresetSeatController({} as never, () => ({ id: SessionId('started'), blank: false, diff --git a/packages/client/ui-chat/README.i18n.yaml b/packages/client/ui-chat/README.i18n.yaml index 044e530fbc..c42928d650 100644 --- a/packages/client/ui-chat/README.i18n.yaml +++ b/packages/client/ui-chat/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-chat/README.md -README.md: 901c97e620a843d5d87964dbfe021c3e33e6fe3f -README.zh.md: 5500f0935c508b1ddce7113cf06003528fc1574b +README.md: b916802917bfdd406fb333174371507d466b8e19 +README.zh.md: 01de4d633cb1501a03200aa96f72e89622d0a7d8 diff --git a/packages/client/ui-chat/README.md b/packages/client/ui-chat/README.md index 901c97e620..b916802917 100644 --- a/packages/client/ui-chat/README.md +++ b/packages/client/ui-chat/README.md @@ -102,6 +102,8 @@ None; Chat presentation does not assemble or mutate provider requests. +- **Developer messages are not displayed** — presentation is intentionally deferred; encountering `developer/message` throws instead of rendering a fallback row. + - **The transcript reflects the loaded Session window** — older transcript nodes become available only after Session Controller loads the preceding event page. Turn navigation is wider than the window: the rail merges the loaded Turns with the host `turnOutline` projection, so every started Turn gets a fixed-pitch mark (10px apart; a ladder taller than the frame scrolls inside it with gradient fades), and activating an unloaded mark pages history through the Turn's `turn/start` seq before landing on its row. Without the projection (assemblies not mounting `dsh-session-turn-outline`) the rail falls back to loaded Turns only. - **Rail previews are card-sized** — one prompt line (50 characters) and up to three response lines (120), on loaded and unloaded Turns alike; an unloaded Turn's response arrives from the outline only once the Turn settled, so an open Turn previews its prompt (or just the Turn number) until then. diff --git a/packages/client/ui-chat/README.zh.md b/packages/client/ui-chat/README.zh.md index 5500f0935c..01de4d633c 100644 --- a/packages/client/ui-chat/README.zh.md +++ b/packages/client/ui-chat/README.zh.md @@ -102,6 +102,8 @@ Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点,并且 +- **不展示 developer 消息** — 展示能力有意留待后续实现;遇到 `developer/message` 时抛出错误,不渲染回退行。 + - **transcript 只反映已加载的 Session 窗口**——只有会话控制器加载前一页事件后,更早的 transcript node 才会出现。轮次导航比窗口更宽:轨道把已加载的轮次与宿主 `turnOutline` 投影合并,每个已开始的轮次都有固定间距刻度(相隔 10px;阶梯高于外框时在框内滚动并以渐变淡出标示可滚方向),激活未加载刻度会先把历史分页拉到该轮次的 `turn/start` seq 再落到它的行上。没有该投影时(未挂载 `dsh-session-turn-outline` 的装配),轨道回退到仅显示已加载轮次。 - **导航预览按卡片尺寸截断**——提示词一行(50 字符)、回复至多三行(120 字符),已加载与未加载 Turn 一致;未加载 Turn 的回复要等该轮落定后才随大纲到达,进行中的轮次在此之前只预览提示词(或仅轮次号)。 diff --git a/packages/client/ui-chat/src/client/chat/TurnTailNodeView.tsx b/packages/client/ui-chat/src/client/chat/TurnTailNodeView.tsx index a03c46b2ed..e8cb78c304 100644 --- a/packages/client/ui-chat/src/client/chat/TurnTailNodeView.tsx +++ b/packages/client/ui-chat/src/client/chat/TurnTailNodeView.tsx @@ -44,7 +44,9 @@ export const TurnTailNodeView = memo(function TurnTailNodeView({ text={assistantText(closing.blocks)} time={closing.time} clock="end" - onBranch={() => { forkAt(closing.finalNode.seq) }} + // The branch action owns boundary resolution: it sends the real + // turn/end seq it already has, and the Host cuts exactly there. + onBranch={() => { forkAt(data.seq) }} branchUnavailable={data.branchUnavailable || hasLaterChatNode} className={css.actions} extraActions={assistantActions} diff --git a/packages/client/ui-chat/src/client/conversation-nodes/command.ts b/packages/client/ui-chat/src/client/conversation-nodes/command.ts index e21f50c5f5..7604d88edc 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/command.ts +++ b/packages/client/ui-chat/src/client/conversation-nodes/command.ts @@ -20,7 +20,7 @@ declare module '../contract/chat-nodes.ts' { type CommandId = CommandNode['commandId'] -const COMPACT_PLUGIN: CompactionCheckpointSource['plugin'] = 'compact' +const COMPACT_KIND: CompactionCheckpointSource['kind'] = 'compact-checkpoint' interface CommandState { readonly command: CommandNode @@ -82,11 +82,10 @@ function compactSource(event: Parameters[0] if (event.type !== 'user/message' || !isReplacementSurfaceEvent(event)) return undefined const source = event.data.source as unknown as { kind?: unknown - plugin?: unknown compactionId?: unknown sourceCommandId?: CommandId } - if (source.kind !== 'plugin' || source.plugin !== COMPACT_PLUGIN || typeof source.compactionId !== 'string') return undefined + if (source.kind !== COMPACT_KIND || typeof source.compactionId !== 'string') return undefined return { compactionId: source.compactionId, ...source.sourceCommandId === undefined ? {} : { sourceCommandId: source.sourceCommandId }, diff --git a/packages/client/ui-chat/src/client/conversation-nodes/event-projection.ts b/packages/client/ui-chat/src/client/conversation-nodes/event-projection.ts index 5995638194..e61bb53109 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/event-projection.ts +++ b/packages/client/ui-chat/src/client/conversation-nodes/event-projection.ts @@ -66,8 +66,6 @@ export function contextProducer(source: unknown): ContextProducerView { return { role: 'recall', label: joined(collect(record, 'references', 'label')) ?? kind } case 'agent-instructions': return { role: 'inject', label: joined(collect(record, 'changes', 'path')) ?? kind } - case 'plugin': - return { role: 'inject', label: readString(record, 'plugin') ?? kind } case 'skill-invocation': return { role: 'inject', label: readString(record, 'name') ?? kind } default: diff --git a/packages/client/ui-chat/src/client/conversation-nodes/message.ts b/packages/client/ui-chat/src/client/conversation-nodes/message.ts index 823bbe3c93..22ebf7cb08 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/message.ts +++ b/packages/client/ui-chat/src/client/conversation-nodes/message.ts @@ -36,19 +36,24 @@ declare module '../contract/chat-nodes.ts' { function isCompactionCheckpoint(event: Parameters[0]): boolean { if (event.type !== 'user/message' || !isReplacementSurfaceEvent(event)) return false - const source = event.data.source - return source.kind === 'plugin' && source.plugin === 'compact' + const source = event.data.source as { kind?: unknown } + return source.kind === 'compact-checkpoint' } /** User, steering, and injected-context message classification Definition. */ export const messageDefinition: ConversationNodeDefinition = { kind: 'input-message', target: 'chat', - match: event => event.type === 'user/message' - && isAppendSurfaceEvent(event) - && !isCompactionCheckpoint(event) - ? { id: String(event.data.id), role: 'start' } - : null, + match: (event) => { + if (event.type === 'user/message') { + return isAppendSurfaceEvent(event) && !isCompactionCheckpoint(event) + ? { id: String(event.data.id), role: 'start' } + : null + } + // Developer history is persisted for V4; presentation is intentionally deferred. + if (event.type === 'developer/message') throw new Error('Chat developer messages are not supported yet') + return null + }, start: (_context, match, reader) => { if (match.event.type !== 'user/message') throw new Error('input-message start requires user/message') const event = match.event diff --git a/packages/client/ui-chat/src/client/conversation-nodes/tool.ts b/packages/client/ui-chat/src/client/conversation-nodes/tool.ts index f6653b92bd..2e914e5072 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/tool.ts +++ b/packages/client/ui-chat/src/client/conversation-nodes/tool.ts @@ -51,16 +51,16 @@ function rootCall(match: ConversationMatch): RunningToolCall { function rootResult(match: ConversationMatch, previous?: RunningToolCall): ToolResultNode | undefined { if (match.event.type !== 'tool/result') return undefined - const result = match.event.data.message.content[0] + const message = match.event.data.message return { kind: 'tool-result', seq: match.event.seq, time: match.event.time, - callId: String(match.event.data.message.source.callId), + callId: String(message.source.callId), call: previous === undefined ? null : { name: previous.name, argsRaw: previous.argsRaw }, callTime: previous?.time ?? null, - content: result.content, - isError: result.isError === true, + content: message.content, + isError: message.isError === true, ...match.event.data.error === undefined ? {} : { error: match.event.data.error }, meta: match.event.data.meta, subCalls: [], diff --git a/packages/client/ui-chat/tests/chat-branch-tails.client.spec.tsx b/packages/client/ui-chat/tests/chat-branch-tails.client.spec.tsx index 4e2493d17c..013ed04786 100644 --- a/packages/client/ui-chat/tests/chat-branch-tails.client.spec.tsx +++ b/packages/client/ui-chat/tests/chat-branch-tails.client.spec.tsx @@ -331,7 +331,7 @@ describe('MessageItem arms', () => { kind: 'context', seq: 3, content: [{ type: 'text', text: 'line one\n\nline two' }], - source: { kind: 'plugin', plugin: 'fixture', empty: {}, list: [] }, + source: { kind: 'fixture', empty: {}, list: [] }, producer: { role: 'inject', label: 'fixture' }, form: null, } as never} @@ -351,7 +351,7 @@ describe('MessageItem arms', () => { expect(ctxView.container.querySelector('[data-context-text]')?.textContent) .toBe('line one\n\nline two') const fields = [...ctxView.container.querySelectorAll('[data-context-fields] dt')].map(node => node.textContent) - expect(fields).toEqual(['plugin', 'empty', 'list']) + expect(fields).toEqual(['empty', 'list']) fireEvent.keyDown(disclosure, { key: ' ' }) expect(disclosure.getAttribute('aria-expanded')).toBe('false') @@ -650,7 +650,7 @@ describe('MessageItem arms', () => { const view = render( { ) fireEvent.click(view.getByRole('button', { name: /^上下文注入\s*later$/ })) const fields = [...view.container.querySelectorAll('[data-context-fields] dt')].map(node => node.textContent) - expect(fields).toEqual(['plugin', 'form']) + expect(fields).toEqual(['form']) }) it('the snapshot form attributes each part to the subsystem that produced it', () => { @@ -668,8 +668,7 @@ describe('MessageItem arms', () => { seq: 3, content: [{ type: 'text', text: 'Current runtime context.\n\nsandbox\n\nworkspace' }], source: { - kind: 'plugin', - plugin: '@deepseek-ai/dsh-system-prompt', + kind: 'runtime-context', form: 'snapshot', sections: [{ name: 'sandbox:policy', text: 'workspace-write' }, { name: 'workspace', text: '/repo' }], }, @@ -690,7 +689,7 @@ describe('MessageItem arms', () => { kind: 'context', seq: 3, content: [{ type: 'text', text: 'background job bash-1 finished.' }], - source: { kind: 'plugin', plugin: 'tool-jobs', form: 'notice', summary: 'bash pnpm test [status: completed]' }, + source: { kind: 'tool-jobs', form: 'notice', summary: 'bash pnpm test [status: completed]' }, producer: { role: 'inject', label: 'tool-jobs' }, form: 'notice', } as never} @@ -705,7 +704,7 @@ describe('MessageItem arms', () => { const view = render( = {}): CompactionSummar /** Empty sessions-list hook for the global standard-kit seat. */ function emptySessions() { const store = createSnapshotStore( - { ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {} }) + { ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {} }) return bindSnapshotSelector(store) } @@ -1086,7 +1086,9 @@ describe('ChatView', () => { expect(branchButtons).toHaveLength(1) expect(branchButtons[0]!.getAttribute('aria-disabled')).toBeNull() fireEvent.click(branchButtons[0]!) - expect(h.forkAt).toHaveBeenCalledWith(1) + // The branch action sends the real turn/end seq (the exact inclusive + // Host boundary), not the assistant node seq. + expect(h.forkAt).toHaveBeenCalledWith(3) }) it('keeps a later pending occurrence visible when it reuses a durable MessageId', () => { @@ -2045,7 +2047,7 @@ describe('ChatView', () => { expect(buttons).toHaveLength(1) expect(buttons[0]!.getAttribute('aria-disabled')).toBeNull() fireEvent.click(buttons[0]!) - expect(h.forkAt.mock.calls).toEqual([[2]]) + expect(h.forkAt.mock.calls).toEqual([[3]]) }) it('disables fork when the indexed Turn has a later steering Node', () => { diff --git a/packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts b/packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts index f393a952bf..f116edab09 100644 --- a/packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts +++ b/packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts @@ -180,7 +180,7 @@ function systemMessage(text: string) { id: `system-${text}`, role: 'system', content: text === '' ? [] : [{ type: 'text', text }], - source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, + source: { kind: 'system-prompt' }, } } @@ -208,18 +208,22 @@ function assistantMessage(id: string, text: string) { function toolResult(callId: string, text: string, isError = false) { return { id: `result-${callId}`, - role: 'user', + role: 'tool', + toolCallId: callId, source: { kind: 'tool', callId }, - content: [{ - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text }], - isError, - }], + content: [{ type: 'text', text }], + isError, } } describe('built-in conversation node Definitions', () => { + it('rejects developer history until presentation is implemented', () => { + expect(() => assembler([at(0, 'developer/message', { turn: 1, step: 1, message: { + id: 'developer', role: 'developer', source: { kind: 'tool-registry' }, + content: [{ type: 'tool-addition', toolName: 'search' }], + } }, { surfaceOp: 'append' })])).toThrow('developer messages are not supported yet') + }) + it('rejects an unrelated event passed directly to the request-prompt start', () => { const input = at(1, 'turn/start', { turn: 1 }) const invalidStart = { @@ -323,7 +327,7 @@ describe('built-in conversation node Definitions', () => { ...textMessage('context-1', 'workspace context'), turn: 1, step: 1, - source: { kind: 'plugin', plugin: 'context' }, + source: { kind: 'context' }, }, { surfaceOp: 'append' }), at(4, 'assistant/live-chunk', { turn: 1, step: 1, chunk: { type: 'reasoning-delta', index: 0, text: 'thinking' }, @@ -456,7 +460,7 @@ describe('built-in conversation node Definitions', () => { at(1, 'turn/start', { turn: 1 }), at(2, 'user/message', { ...textMessage('context-1', 'runtime context'), - source: { kind: 'plugin', plugin: 'context' }, + source: { kind: 'context' }, }, { surfaceOp: 'append' }), at(3, 'user/message', textMessage('user-1', 'question'), { surfaceOp: 'append' }), at(4, 'step/start', { turn: 1, step: 1 }), @@ -622,7 +626,7 @@ describe('built-in conversation node Definitions', () => { at(1, 'turn/start', { turn: 1 }), at(2, 'user/message', { ...textMessage('context-1', 'runtime context'), - source: { kind: 'plugin', plugin: 'context' }, + source: { kind: 'context' }, }, { surfaceOp: 'append' }), at(3, 'step/start', { turn: 1, step: 1 }), at(4, 'assistant/live-chunk', { @@ -1612,7 +1616,7 @@ describe('built-in conversation node Definitions', () => { at(4, 'user/message', textMessage('direct-user', 'prompt'), { surfaceOp: 'append' }), at(5, 'user/message', { ...textMessage('runtime-context', 'runtime facts'), - source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt', form: 'snapshot' }, + source: { kind: 'runtime-context', form: 'snapshot' }, }, { surfaceOp: 'append' }), at(6, 'request/header', { reason: 'initial', @@ -1647,7 +1651,7 @@ describe('built-in conversation node Definitions', () => { at(11, 'step/start', { turn: 1, step: 3 }), at(12, 'user/message', { turn: 1, step: 3, id: 'summary', role: 'user', - content: [{ type: 'text', text: 'summary' }], source: { kind: 'plugin', plugin: 'compaction' }, + content: [{ type: 'text', text: 'summary' }], source: { kind: 'compact-checkpoint', compactionId: 'compaction-1' }, }, { surfaceOp: { op: 'replace', startSeq: 5, endSeq: 9 }, sourceEventSeqs: [5, 8, 9] }), at(13, 'request/header', { reason: 'series', header: { config: { provider: 'test', model: 'test' }, tools: [] }, @@ -1791,7 +1795,7 @@ describe('built-in conversation node Definitions', () => { at(4, 'user/message', textMessage('direct-user', 'prompt'), { surfaceOp: 'append' }), at(5, 'user/message', { ...textMessage('runtime-context', 'runtime facts'), - source: { kind: 'plugin', plugin: 'context' }, + source: { kind: 'context' }, }, { surfaceOp: 'append' }), at(6, 'request/header', { reason: 'initial', @@ -1910,7 +1914,7 @@ describe('built-in conversation node Definitions', () => { }), at(6, 'user/message', { ...textMessage('compacted', 'summary'), - source: { kind: 'plugin', plugin: 'compact' }, + source: { kind: 'compact-checkpoint', compactionId: 'chat-compaction-1' }, }, { surfaceOp: { op: 'replace', startSeq: 4, endSeq: 4 } }), at(7, 'request/header', { reason: 'series', @@ -2091,7 +2095,7 @@ describe('built-in conversation node Definitions', () => { at(2, 'step/start', { turn: 1, step: 1 }), at(3, 'user/message', { ...textMessage('replacement-user', 'model-only context'), - source: { kind: 'plugin', plugin: 'foreign' }, + source: { kind: 'foreign' }, }, { surfaceOp: { op: 'replace', startSeq: 1, endSeq: 1 } }), at(4, 'assistant/message', { turn: 1, @@ -2179,8 +2183,7 @@ describe('built-in conversation node Definitions', () => { at(13, 'user/message', { ...textMessage('manual-checkpoint', 'checkpoint'), source: { - kind: 'plugin', - plugin: 'compact', + kind: 'compact-checkpoint', compactionId: 'manual-1', sourceCommandId: 'command-1', }, @@ -2204,7 +2207,7 @@ describe('built-in conversation node Definitions', () => { }), at(22, 'user/message', { ...textMessage('automatic-checkpoint', 'checkpoint'), - source: { kind: 'plugin', plugin: 'compact', compactionId: 'automatic-1' }, + source: { kind: 'compact-checkpoint', compactionId: 'automatic-1' }, }, { surfaceOp: { op: 'replace', startSeq: 3, endSeq: 4 } }), at(23, 'compaction/end', { compactionId: 'automatic-1', turn: null }), ]) @@ -2223,7 +2226,7 @@ describe('built-in conversation node Definitions', () => { const value = assembler([ at(13, 'user/message', { ...textMessage('checkpoint', 'checkpoint'), - source: { kind: 'plugin', plugin: 'compact', compactionId: 'compact-1' }, + source: { kind: 'compact-checkpoint', compactionId: 'compact-1' }, }, { surfaceOp: { op: 'replace', startSeq: 1, endSeq: 8 } }), ], true) const before = node(snapshot(value), 'compaction') @@ -2264,7 +2267,7 @@ describe('built-in conversation node Definitions', () => { }), at(11, 'user/message', { ...textMessage('checkpoint-windowed', 'checkpoint'), - source: { kind: 'plugin', plugin: 'compact', compactionId: 'compact-windowed' }, + source: { kind: 'compact-checkpoint', compactionId: 'compact-windowed' }, }, { surfaceOp: { op: 'replace', startSeq: 1, endSeq: 3 } }), ], true) @@ -2288,7 +2291,7 @@ describe('built-in conversation node Definitions', () => { }), at(22, 'user/message', { ...textMessage('legacy-checkpoint', 'checkpoint'), - source: { kind: 'plugin', plugin: 'compact' }, + source: { kind: 'compact-checkpoint' }, }, { surfaceOp: { op: 'replace', startSeq: 1, endSeq: 3 } }), at(23, 'compaction/end', { turn: null }), ], true) @@ -2494,8 +2497,7 @@ describe('built-in conversation node Definitions', () => { at(21, 'user/message', { ...textMessage('manual-checkpoint', 'checkpoint'), source: { - kind: 'plugin', - plugin: 'compact', + kind: 'compact-checkpoint', compactionId: 'manual-1', sourceCommandId: 'command-1', }, diff --git a/packages/client/ui-chat/tests/event-projection.client.spec.ts b/packages/client/ui-chat/tests/event-projection.client.spec.ts index f1818da09c..c895f8a3bc 100644 Binary files a/packages/client/ui-chat/tests/event-projection.client.spec.ts and b/packages/client/ui-chat/tests/event-projection.client.spec.ts differ diff --git a/packages/client/ui-chat/tests/transcript-view-row.client.spec.tsx b/packages/client/ui-chat/tests/transcript-view-row.client.spec.tsx index ad2896b854..ca5aeb1e00 100644 --- a/packages/client/ui-chat/tests/transcript-view-row.client.spec.tsx +++ b/packages/client/ui-chat/tests/transcript-view-row.client.spec.tsx @@ -16,7 +16,7 @@ afterEach(cleanup) function emptySessions() { return bindSnapshotSelector(createSnapshotStore({ - ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {}, })) } diff --git a/packages/client/ui-conversation/src/client/contract/records.ts b/packages/client/ui-conversation/src/client/contract/records.ts index cb2b327fcc..c4bd56c026 100644 --- a/packages/client/ui-conversation/src/client/contract/records.ts +++ b/packages/client/ui-conversation/src/client/contract/records.ts @@ -197,13 +197,9 @@ export interface CompactionSummaryNode { } /** - * Fallback for surface events this UI version does not know: the documented - * default arm of `SessionEventMap`, which is merge-extensible, so the - * projection's switch cannot end in `assertNever`. No event produces this node - * because `isAppendSurfaceEvent` admits only the four types in core's - * `SurfaceEventType`, and each has its own arm (`system/message` is claimed by - * a Chat Definition that renders no transcript row) — and it exists so widening - * that set core-side degrades to a raw row instead of dropping the event silently. + * Fallback for unclaimed append-surface events. The merge-extensible + * SessionEventMap permits unfamiliar events to retain a raw presentation. + * Known unsupported developer events throw before fallback selection. */ export interface UnknownSurfaceNode { kind: 'unknown' diff --git a/packages/client/ui-conversation/src/client/skeleton/ConversationMainPanel.tsx b/packages/client/ui-conversation/src/client/skeleton/ConversationMainPanel.tsx index d156480507..d3c3a9f600 100644 --- a/packages/client/ui-conversation/src/client/skeleton/ConversationMainPanel.tsx +++ b/packages/client/ui-conversation/src/client/skeleton/ConversationMainPanel.tsx @@ -27,8 +27,8 @@ export function ConversationMainPanel(props: ConversationSlotProps) { // The exemption is deliberately open-state-wide, not loading-only: a // summary-blank session is the hero before its open starts (`cold`) and // after one fails (`error`) for the same reason — there is no history. - // A restored continuable subagent also stays settled until its eagerly - // loaded parent catalog establishes availability. This keeps the composer + // A restored continuable subagent waits for a Host summary to establish + // parent availability. This keeps the composer // hidden instead of briefly rendering the parent-offline takeover. const parentAvailabilityPending = session?.subagent?.address.mode === 'continuable' && session.subagent.parentAvailable === undefined diff --git a/packages/client/ui-conversation/tests/conversation-registry.client.spec.ts b/packages/client/ui-conversation/tests/conversation-registry.client.spec.ts index d063279939..8a919e624c 100644 --- a/packages/client/ui-conversation/tests/conversation-registry.client.spec.ts +++ b/packages/client/ui-conversation/tests/conversation-registry.client.spec.ts @@ -71,7 +71,7 @@ function fakeSessions(ctx: Context): { sessions: ISessions; binding: SessionBind ids: [], byId: {}, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, }) const reference = { @@ -89,8 +89,7 @@ function fakeSessions(ctx: Context): { sessions: ISessions; binding: SessionBind using: async (_target, _options, operation) => await operation(reference), retainInfo: () => createSnapshotStore({ referenceCount: 1, retainedBy: {} }), subagentAddress: () => undefined, - setSubagentCatalogOpen: () => {}, - refreshSubagents: () => Promise.reject(new Error('unused fake Sessions operation')), + refreshProjections: () => Promise.reject(new Error('unused fake Sessions operation')), refresh: () => Promise.reject(new Error('unused fake Sessions operation')), search: () => Promise.reject(new Error('unused fake Sessions operation')), fork: () => Promise.reject(new Error('unused fake Sessions operation')), diff --git a/packages/client/ui-conversation/tests/enter-behavior-row.client.spec.tsx b/packages/client/ui-conversation/tests/enter-behavior-row.client.spec.tsx index 48f7ee1f62..b5de7d3ade 100644 --- a/packages/client/ui-conversation/tests/enter-behavior-row.client.spec.tsx +++ b/packages/client/ui-conversation/tests/enter-behavior-row.client.spec.tsx @@ -22,7 +22,7 @@ afterEach(() => { function emptySessions() { return bindSnapshotSelector(createSnapshotStore({ - ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {}, })) } diff --git a/packages/client/ui-conversation/tests/input-bar.client.spec.tsx b/packages/client/ui-conversation/tests/input-bar.client.spec.tsx index 74140e0946..9e0366952c 100644 --- a/packages/client/ui-conversation/tests/input-bar.client.spec.tsx +++ b/packages/client/ui-conversation/tests/input-bar.client.spec.tsx @@ -175,7 +175,7 @@ function bench(over?: BenchOptions) { useResource, useSessions: bindSnapshotSelector(createSnapshotStore({ ids: [], byId: {}, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, })), useWorkspaces: bindSnapshotSelector(createSnapshotStore({ items: [], archivedSessionIds: [], pinnedSessionIds: [], state: 'idle', phase: 'ready', error: null, diff --git a/packages/client/ui-conversation/tests/input-matrix.client.spec.tsx b/packages/client/ui-conversation/tests/input-matrix.client.spec.tsx index 6b65e8aeb0..15d87a0ca7 100644 --- a/packages/client/ui-conversation/tests/input-matrix.client.spec.tsx +++ b/packages/client/ui-conversation/tests/input-matrix.client.spec.tsx @@ -54,7 +54,7 @@ function mountBar(shell: SessionInputShell, over?: { running?: boolean; disabled useSession: bindSnapshotSelector(session), useSessions: bindSnapshotSelector(createSnapshotStore({ ids: [], byId: {}, current: undefined, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, currentAddress: undefined, + projectionsBySession: {}, jobsBySession: {}, currentAddress: undefined, })), useSessionStatus: bindSnapshotSelector( createSnapshotStore(new Map()), diff --git a/packages/client/ui-conversation/tests/input-scenarios.client.spec.tsx b/packages/client/ui-conversation/tests/input-scenarios.client.spec.tsx index 44b4a48ade..347b4d05c1 100644 --- a/packages/client/ui-conversation/tests/input-scenarios.client.spec.tsx +++ b/packages/client/ui-conversation/tests/input-scenarios.client.spec.tsx @@ -148,7 +148,7 @@ async function scopedBench(register?: (inputTriggers: InputTriggerService) => vo useSession: bindSnapshotSelector(sessionStore), useSessions: bindSnapshotSelector(createSnapshotStore({ ids: [], byId: {}, current: undefined, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, currentAddress: undefined, + projectionsBySession: {}, jobsBySession: {}, currentAddress: undefined, })), useSessionStatus: bindSnapshotSelector( createSnapshotStore(new Map()), diff --git a/packages/client/ui-conversation/tests/skeleton.client.spec.tsx b/packages/client/ui-conversation/tests/skeleton.client.spec.tsx index c216f64f20..17aadfb056 100644 --- a/packages/client/ui-conversation/tests/skeleton.client.spec.tsx +++ b/packages/client/ui-conversation/tests/skeleton.client.spec.tsx @@ -164,7 +164,7 @@ function mount( ...listed && options.nestedSubagent === true && { [parent]: parentRow }, ...listed && { [SID]: childRow }, }, - phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + phase: 'ready', projectionsBySession: {}, jobsBySession: {}, }) const workspaces = createSnapshotStore(workspaceState(workspaceRows)) const session = createSnapshotStore(snapshot) diff --git a/packages/client/ui-conversation/tests/system-prompt.client.spec.ts b/packages/client/ui-conversation/tests/system-prompt.client.spec.ts index 4604de6f4b..4411cfb9c7 100644 --- a/packages/client/ui-conversation/tests/system-prompt.client.spec.ts +++ b/packages/client/ui-conversation/tests/system-prompt.client.spec.ts @@ -7,7 +7,7 @@ function system(seq: number, text: string, replaces?: number): SessionEvent { seq, time: seq, type: 'system/message', data: { turn: 1, step: seq, message: { role: 'system', content: [{ type: 'text', text }] } }, surfaceOp: replaces === undefined ? 'append' : { op: 'replace', startSeq: replaces, endSeq: replaces }, - } as SessionEvent + } as unknown as SessionEvent } function replace(seq: number, start: number, end: number): SessionEvent { diff --git a/packages/client/ui-deliverables/src/client/turn-deliverables.ts b/packages/client/ui-deliverables/src/client/turn-deliverables.ts index 87d13e5e41..7eb765ec2b 100644 --- a/packages/client/ui-deliverables/src/client/turn-deliverables.ts +++ b/packages/client/ui-deliverables/src/client/turn-deliverables.ts @@ -200,8 +200,7 @@ export const deliverablesDefinition: ConversationNodeDefinition(select: (value: boolean) => T): T => select(true), useSessions: (select: (state: SessionListState) => T): T => select(sessions), @@ -185,8 +185,12 @@ function result(seq: number, callId: string, isError = false, turn = 1): Session turn, step: 1, message: { - source: { type: 'tool-result', callId }, - content: [{ type: 'tool-result', content: [], isError }], + id: `result-${callId}`, + role: 'tool', + toolCallId: callId, + source: { kind: 'tool', callId }, + content: [], + isError, }, }) } diff --git a/packages/client/ui-jobs/tests/job-list-action.client.spec.tsx b/packages/client/ui-jobs/tests/job-list-action.client.spec.tsx index d82f2b0c47..e42e0ef556 100644 --- a/packages/client/ui-jobs/tests/job-list-action.client.spec.tsx +++ b/packages/client/ui-jobs/tests/job-list-action.client.spec.tsx @@ -40,7 +40,7 @@ function props(jobs: readonly JobView[] | undefined): JobListActionProps { ids: [SESSION], byId: {}, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: jobs === undefined ? {} : { [SESSION]: jobs }, } satisfies SessionListState function useSessions(select: (snapshot: SessionListState) => T): T { diff --git a/packages/client/ui-layout/tests/app-frame.client.spec.tsx b/packages/client/ui-layout/tests/app-frame.client.spec.tsx index 2ffd6ef7fe..b097c4b62c 100644 --- a/packages/client/ui-layout/tests/app-frame.client.spec.tsx +++ b/packages/client/ui-layout/tests/app-frame.client.spec.tsx @@ -77,7 +77,7 @@ function mountFrame(windowWidth = frameWidth) { }, }, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, }) const workspaceState: WorkspaceSnapshot = { diff --git a/packages/client/ui-layout/tests/document-title.client.spec.tsx b/packages/client/ui-layout/tests/document-title.client.spec.tsx index eb77ab430c..0aefd57215 100644 --- a/packages/client/ui-layout/tests/document-title.client.spec.tsx +++ b/packages/client/ui-layout/tests/document-title.client.spec.tsx @@ -20,7 +20,7 @@ function titleSources() { ids: [sessionId], byId: { [sessionId]: { id: sessionId, displayTitle: 'Test', running: false, retainedBy: { mainView: 1 }, blank: false, updatedAt: 1 } }, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, }) const panelInfo = createSnapshotStore({ activePanelId: null }) diff --git a/packages/client/ui-model-selection/README.i18n.yaml b/packages/client/ui-model-selection/README.i18n.yaml index f0ed9ac063..671cf8ecc9 100644 --- a/packages/client/ui-model-selection/README.i18n.yaml +++ b/packages/client/ui-model-selection/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-model-selection/README.md -README.md: 5e16cdf18d2eccb63097c2a524bfb2d20178d15e -README.zh.md: a99581e827c5ce66a31f6e4cbad11394e03dde4d +README.md: 20d55111a298076a7f41db3a7bcd859f2c8433a6 +README.zh.md: d60c811e7fdd57936f11963916a835064e1fff96 diff --git a/packages/client/ui-model-selection/README.md b/packages/client/ui-model-selection/README.md index 5e16cdf18d..20d55111a2 100644 --- a/packages/client/ui-model-selection/README.md +++ b/packages/client/ui-model-selection/README.md @@ -35,6 +35,8 @@ Models stay grouped by provider. The composer menu shows model and effort names When the Host reports that no adapter serves the session's route, this plugin raises a composer block and the input goes inert with its own copy; recovering clears it without a reload. A `null` before the first load or after one failed never blocks, and catalog membership never blocks either — a route serving a model it does not advertise is missing from the groups yet usable. +Only the current Client binding's directory can publish its composer block. Cleanup from an older binding preserves a replacement directory's block; without a replacement directory, cleanup removes the obsolete block. + ### Selection failures When another writer owns the Session, model-selection failures tell the user to quit other running DSH instances and retry. diff --git a/packages/client/ui-model-selection/README.zh.md b/packages/client/ui-model-selection/README.zh.md index a99581e827..d60c811e7f 100644 --- a/packages/client/ui-model-selection/README.zh.md +++ b/packages/client/ui-model-selection/README.zh.md @@ -35,6 +35,8 @@ Web GUI 允许用户通过 `/model` 弹窗或 composer 模型控件切换既有 当 Host 报告没有适配器服务该会话的路由时,本插件注册一个 composer 阻塞块,输入框随之停用并显示本插件自己的文案;恢复后无需重新加载即清除。首次加载之前或加载失败之后的 `null` 绝不阻断;目录成员关系同样不阻断——一条仍在服务、只是不公布该模型的路由不在分组里,却可用。 +只有当前 Client binding 的目录可以发布对应的 composer 阻塞块。旧 binding 的清理保留后继目录的阻塞块;若尚无后继目录,则移除已失效的阻塞块。 + ### 选择失败 当会话被其他写句柄占用时,模型选择失败提示用户退出其他正在运行的 DSH 后重试。 diff --git a/packages/client/ui-model-selection/src/client/service.ts b/packages/client/ui-model-selection/src/client/service.ts index 03f653f50d..d92c2c08b3 100644 --- a/packages/client/ui-model-selection/src/client/service.ts +++ b/packages/client/ui-model-selection/src/client/service.ts @@ -28,7 +28,7 @@ declare module '@deepseek-ai/cordis' { /** Live mutable state in one holder (service methods run behind the caller-ctx tracker). */ interface LiveState { - /** Per-session directories; entries are deleted by their scope disposer. */ + /** Directories keyed by Client binding, removed by their scope disposer. */ readonly directories: WeakMapWithValues } @@ -91,6 +91,7 @@ export class ModelDirectoryResolver extends Service { const conversation = this.ctx.get('conversation') if (conversation !== undefined) { const publish = (): void => { + if (sessions.binding(sessionId) !== binding) return conversation.blocks.set(sessionId, directory.store.getSnapshot().routable === false ? { reason: this.blockReason() } : undefined) @@ -100,6 +101,8 @@ export class ModelDirectoryResolver extends Service { const stop = directory.store.subscribe(publish) return () => { stop() + const current = sessions.binding(sessionId) + if (current !== undefined && current !== binding && live.directories.get(current) !== undefined) return conversation.blocks.set(sessionId, undefined) } }, 'ui-model-selection: composer block') diff --git a/packages/client/ui-model-selection/tests/browser-plugin.client.spec.ts b/packages/client/ui-model-selection/tests/browser-plugin.client.spec.ts index 47dfb1e5c5..ecae6a1281 100644 --- a/packages/client/ui-model-selection/tests/browser-plugin.client.spec.ts +++ b/packages/client/ui-model-selection/tests/browser-plugin.client.spec.ts @@ -168,7 +168,7 @@ async function bench(locale: 'zh' | 'en' = 'zh') { handle.ctx.effect(() => () => { if (bindings.get(id) === binding) bindings.delete(id) }) - return handle + return { ...handle, projection } } return { ctx, fiber, mint, calls, remote, @@ -353,6 +353,68 @@ describe('ui-model-selection dual entry', () => { expect(face2.directory).not.toBe(face1.directory) }) + it('keeps the replacement directory block when the previous scope finishes cleanup', async () => { + const b = await bench() + const first = b.mint('s1') + const oldDirectory = b.ctx.modelDirectories.directoryFor(sid('s1')) + await oldDirectory.load() + const replacement = b.mint('s1') + replacement.projection.set({ lastUsed: null, next: { provider: 'missing', model: 'unserved' } }) + const directory = b.ctx.modelDirectories.directoryFor(sid('s1')) + try { + expect(directory).not.toBe(oldDirectory) + expect(directory.store.getSnapshot().routable).toBe(false) + expect(b.blockOf('s1')?.reason).toBe(zh['blocked.composer']) + await first.fiber.dispose() + expect(b.blockOf('s1')?.reason).toBe(zh['blocked.composer']) + await replacement.fiber.dispose() + expect(b.blockOf('s1')).toBeUndefined() + } finally { + await Promise.all([first.fiber.dispose(), replacement.fiber.dispose()]) + await b.ctx.fiber.dispose() + } + }) + + it.each([false, true])('ignores late old projection publication while the replacement is routable=%s', async (routable) => { + const b = await bench() + const first = b.mint('s1') + const oldDirectory = b.ctx.modelDirectories.directoryFor(sid('s1')) + await oldDirectory.load() + const replacement = b.mint('s1') + replacement.projection.set({ lastUsed: null, + next: { provider: routable ? 'deepseek-official' : 'missing', model: 'replacement' } }) + const directory = b.ctx.modelDirectories.directoryFor(sid('s1')) + try { + expect(directory.store.getSnapshot().routable).toBe(routable) + const expected = b.blockOf('s1') + await Promise.resolve().then(() => { + first.projection.set({ lastUsed: null, + next: { provider: routable ? 'missing' : 'deepseek-official', model: 'late-old' } }) + }) + expect(oldDirectory.store.getSnapshot().routable).toBe(!routable) + expect(b.blockOf('s1')).toBe(expected) + } finally { + await Promise.all([first.fiber.dispose(), replacement.fiber.dispose()]) + await b.ctx.fiber.dispose() + } + }) + + it('clears an obsolete block when the new binding has no model directory', async () => { + const b = await bench() + const first = b.mint('s1') + first.projection.set({ lastUsed: null, next: { provider: 'missing', model: 'unserved' } }) + await b.ctx.modelDirectories.directoryFor(sid('s1')).load() + const replacement = b.mint('s1') + try { + expect(b.blockOf('s1')).toBeDefined() + await first.fiber.dispose() + expect(b.blockOf('s1')).toBeUndefined() + } finally { + await Promise.all([first.fiber.dispose(), replacement.fiber.dispose()]) + await b.ctx.fiber.dispose() + } + }) + it('blocks the composer only once the Host reports the route unservable', async () => { const b = await bench() b.mint('s1') diff --git a/packages/client/ui-open-in-app/tests/open-in-app-action.client.spec.tsx b/packages/client/ui-open-in-app/tests/open-in-app-action.client.spec.tsx index f108723d5e..62f1ba2295 100644 --- a/packages/client/ui-open-in-app/tests/open-in-app-action.client.spec.tsx +++ b/packages/client/ui-open-in-app/tests/open-in-app-action.client.spec.tsx @@ -34,7 +34,7 @@ function bench(over: { byId: over.cwd === undefined ? {} : { [SESSION]: { cwd: over.cwd } }, current: SESSION, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, currentAddress: undefined, } as unknown as SessionListState diff --git a/packages/client/ui-plan/README.i18n.yaml b/packages/client/ui-plan/README.i18n.yaml index 2b68bc2db2..74be8bbf76 100644 --- a/packages/client/ui-plan/README.i18n.yaml +++ b/packages/client/ui-plan/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-plan/README.md -README.md: 0ba994c4003dc5a3be5be11f217435692039f380 -README.zh.md: 5de065cb59d597261628b43607a45ad46d098e1b +README.md: b6072cd7d75446a0a45abe4009273235e4ff4e1b +README.zh.md: 44b5ce85ccd6250f30904f80b01ee083f804f1ce diff --git a/packages/client/ui-plan/README.md b/packages/client/ui-plan/README.md index 0ba994c400..b6072cd7d7 100644 --- a/packages/client/ui-plan/README.md +++ b/packages/client/ui-plan/README.md @@ -35,7 +35,7 @@ While the effective target is plan mode, the seat renders the blue "Plan ×" sta When a Turn ends, each submitted plan appears in its final artifact area, using the file-delivery card treatment with a Markdown icon, title, and Open action. A pending plan opens automatically once per submission in the current browser session. Closing it stays effective across review remounts; a new submission opens its own plan. Historical cards open only when clicked. Use the card or review strip’s View full plan link to read the complete Markdown. Plan tabs show a plain text file icon. Different submissions retain separate tabs; the review buttons alone decide whether implementation may begin. -A review without a logged invocation also opens automatically. Its complete text lives only in the tab’s navigation memory, and the pending review card can reopen it. Reloading the page loses that text; an expired preview directs the user back to a pending review. +A review without a logged invocation also opens automatically. Its complete text lives only in the tab’s navigation memory, and the pending review card can reopen it. Reloading the page loses that text; an expired preview directs the user back to a pending review. Plans opened from an embedded child conversation use the visible sidebar while retaining the child’s address for document reads. ### Failures diff --git a/packages/client/ui-plan/README.zh.md b/packages/client/ui-plan/README.zh.md index 5de065cb59..44b5ce85cc 100644 --- a/packages/client/ui-plan/README.zh.md +++ b/packages/client/ui-plan/README.zh.md @@ -35,7 +35,7 @@ kind: "package-reference" 回合结束后,每次提交的计划都会显示在该回合末尾的产物区域,并采用文件产物卡片的样式,包含 Markdown 图标、标题和“打开”操作。在当前浏览器会话中,每份待审计划自动打开一次;关闭后,重新挂载审批组件不会再次展开,新提交会打开其对应计划。历史卡片仅在点击后打开。通过卡片或审批条带上的“查看全文”链接可阅读完整 Markdown。计划标签页显示纯文本文件图标。不同提交保留独立标签页;是否开始实施仍由审批按钮决定。 -没有已记录调用标识的审批也会自动打开。完整正文只保存在标签页的导航内存中,待处理审批卡片可以重新打开它。刷新页面会丢失该正文;失效的预览会提示用户返回待处理审批。 +没有已记录调用标识的审批也会自动打开。完整正文只保存在标签页的导航内存中,待处理审批卡片可以重新打开它。刷新页面会丢失该正文;失效的预览会提示用户返回待处理审批。在嵌入式子对话中打开计划时,预览使用当前可见的侧栏,读取文档仍保留子会话地址。 ### 失败 diff --git a/packages/client/ui-plan/src/client/index.ts b/packages/client/ui-plan/src/client/index.ts index 4a69be9469..bd0a270474 100644 --- a/packages/client/ui-plan/src/client/index.ts +++ b/packages/client/ui-plan/src/client/index.ts @@ -71,7 +71,7 @@ export function apply(ctx: ClientContext): void { openPlan: (callId) => { const child = ctx.sessions.subagentAddress(sessionId) const session = child === undefined ? { kind: 'session' as const, sessionId } : { kind: 'subagent' as const, ...child } - ctx.sidebarRight.openResourceIn(sessionId, planAddress({ session, callId })) + ctx.sidebarRight.openResource(planAddress({ session, callId })) }, }) const reviewWindow = randomUUID() @@ -84,7 +84,7 @@ export function apply(ctx: ClientContext): void { inject: (sessionId: SessionId): PlanReviewOpenInjected => ({ openReview: (review, requestKey) => { if (review.callId !== undefined) { open(sessionId).openPlan(review.callId); return } - ctx.sidebarRight.openResourceIn(sessionId, reviewPreviewAddress(sessionId, `${reviewWindow}:${requestKey}`), { + ctx.sidebarRight.openResource(reviewPreviewAddress(sessionId, `${reviewWindow}:${requestKey}`), { params: { planReview: { markdown: review.plan, title: extractMarkdownPlainText(review.plan, { mode: 'first-line' }) } }, }) }, diff --git a/packages/client/ui-plan/tests/browser-plugin.client.spec.ts b/packages/client/ui-plan/tests/browser-plugin.client.spec.ts index bbc55871ed..71bc23a044 100644 --- a/packages/client/ui-plan/tests/browser-plugin.client.spec.ts +++ b/packages/client/ui-plan/tests/browser-plugin.client.spec.ts @@ -19,21 +19,25 @@ import { submittedPlan } from '../src/client/plan.ts' import type { PlanChipInjected } from '../src/client/index.ts' import { apply, inject } from '../src/client/index.ts' import { apply as nodeApply } from '../src/index.ts' +import { createSidebarRightController } from '@deepseek-ai/dsh-client-ui-sidebar-right/src/client/service.ts' +import { SidebarRightTabRegistry } from '@deepseek-ai/dsh-client-ui-sidebar-right/src/client/tab-registry.ts' +import { createSidebarRightStore } from '@deepseek-ai/dsh-client-ui-sidebar-right/src/client/stores.ts' function providePreview(ctx: Context) { const events = new ConversationEventRegistry(ctx) ctx.provide('uiConversation', { events }) const removeResources = vi.fn() const removeType = vi.fn() - const registerType = vi.fn((_definition: Parameters[0]) => removeType) + const registerType = vi.fn(() => removeType) const openResourceIn = vi.fn() + const openResource = vi.fn() const subagentAddress = vi.fn(() => undefined) ctx.provide('sessions', { subagentAddress }) ctx.provide('resources', { register: vi.fn(() => removeResources) }) ctx.provide('sidebarRightTabs', { register: registerType }) - ctx.provide('sidebarRight', { openResourceIn }) + ctx.provide('sidebarRight', { openResourceIn, openResource }) ctx.provide('remote.session', {}) - return { events, removeResources, removeType, registerType, openResourceIn, subagentAddress } + return { events, removeResources, removeType, registerType, openResourceIn, openResource, subagentAddress } } const SID = 's-plan' as SessionId @@ -63,6 +67,45 @@ async function bench() { } describe('ui-plan browser apply', () => { + it('opens an embedded child plan in the visible parent sidebar without adopting a child store', async () => { + const b = await bench() + const parent = 'visible-parent' as SessionId + const child = 'embedded-child' as SessionId + const tabs = new SidebarRightTabRegistry(b.ctx) + b.registerType.mockImplementation(definition => tabs.register(definition)) + const store = createSidebarRightStore(() => ({ kind: 'guide', title: 'Guide' })).create() + const { controller, adopt } = createSidebarRightController(tabs, vi.fn()) + const release = adopt(parent, store) + store.actions.open(parent) + const unbind = controller.bind({ + sessionId: parent, actions: store.actions, surfaces: store.getSnapshot().bySession, canSplitPane: () => true, + }) + b.openResource.mockImplementation(controller.openResource.bind(controller)) + b.openResourceIn.mockImplementation(controller.openResourceIn.bind(controller)) + b.subagentAddress.mockReturnValue({ parentSessionId: parent, childSessionId: child, mode: 'continuable' }) + const fiber = b.ctx.plugin({ inject: [...inject], apply }) + try { + await fiber.await() + const card = b.slots.entries('conversation.chat.turnTail')[0]! + const opener = (card.inject as unknown as (sessionId: SessionId) => PlanOpenInjected)(child) + const plan = submittedPlan({ type: 'tool/call', data: { callId: 'child-plan', name: 'exit_plan_mode', arguments: '{"plan":"# Child plan"}' } })! + opener.openPlan(plan.callId) + const resources = () => Object.values(store.getSnapshot().bySession[parent]!.layout.tabs).map(tab => tab.contentId) + expect(resources()).toContain('dsh-resource://plan/subagent/visible-parent/embedded-child/continuable/child-plan') + expect(store.getSnapshot().bySession[child]).toBeUndefined() + const review = b.slots.entries('conversation.plan-review.actions')[0]! + const reviewOpener = (review.inject as unknown as (sessionId: SessionId) => PlanReviewOpenInjected)(child) + reviewOpener.openReview({ id: 'pending', question: 'Approve?', plan: '# Temporary child plan', approve: { label: 'Approve' } }, 'child-question') + expect(resources().some(address => address.startsWith('dsh-resource://plan-review/embedded-child/'))).toBe(true) + expect(store.getSnapshot().bySession[child]).toBeUndefined() + } finally { + await fiber.dispose() + unbind() + release() + controller.tabDomain.dispose() + } + }) + it('declares every service it binds', () => { expect(inject).toEqual(['slots', 'remote', 'remote.commands', 'remote.session', 'sessions', 'locale', 'uiConversation', 'resources', 'sidebarRight', 'sidebarRightTabs']) }) @@ -136,29 +179,29 @@ describe('ui-plan browser apply', () => { expect(card.component).toBe(PlanCards) const injected = (card.inject as unknown as (sessionId: SessionId) => PlanOpenInjected)(SID) injected.openPlan(plan.callId) - expect(b.openResourceIn).toHaveBeenLastCalledWith(SID, address) + expect(b.openResource).toHaveBeenLastCalledWith(address) const review = b.slots.entries('conversation.plan-review.actions')[0]! expect(review.component).toBe(PlanReviewOpen) const reviewInjected = (review.inject as unknown as (sessionId: SessionId) => PlanReviewOpenInjected)(SID) const pending = { id: 'review', question: 'Approve?', plan: plan.markdown, callId: plan.callId, approve: { label: 'Approve' } } reviewInjected.openReview(pending, 'question:1') - expect(b.openResourceIn).toHaveBeenLastCalledWith(SID, address) + expect(b.openResource).toHaveBeenLastCalledWith(address) b.subagentAddress.mockReturnValue({ parentSessionId: 'parent' as SessionId, childSessionId: SID, mode: 'continuable' }) injected.openPlan(plan.callId) - expect(b.openResourceIn).toHaveBeenLastCalledWith(SID, 'dsh-resource://plan/subagent/parent/s-plan/continuable/call') + expect(b.openResource).toHaveBeenLastCalledWith('dsh-resource://plan/subagent/parent/s-plan/continuable/call') reviewInjected.openReview(pending, 'question:1') - expect(b.openResourceIn).toHaveBeenLastCalledWith(SID, 'dsh-resource://plan/subagent/parent/s-plan/continuable/call') + expect(b.openResource).toHaveBeenLastCalledWith('dsh-resource://plan/subagent/parent/s-plan/continuable/call') const temporary = { id: 'review', question: 'Approve?', plan: '# Temporary\n\nComplete body', approve: { label: 'Approve' } } reviewInjected.openReview(temporary, 'question:2') - const first = b.openResourceIn.mock.calls.at(-1)! - expect(type.canOpen!(first[1])).toBe(true) - expect(first).toEqual([SID, expect.stringMatching(/^dsh-resource:\/\/plan-review\/s-plan\//), { + const first = b.openResource.mock.calls.at(-1)! + expect(type.canOpen!(first[0])).toBe(true) + expect(first).toEqual([expect.stringMatching(/^dsh-resource:\/\/plan-review\/s-plan\//), { params: { planReview: { title: 'Temporary', markdown: temporary.plan } }, }]) reviewInjected.openReview(temporary, 'question:2') - expect(b.openResourceIn).toHaveBeenLastCalledWith(...first) + expect(b.openResource).toHaveBeenLastCalledWith(...first) reviewInjected.openReview(temporary, 'question:3') - expect(b.openResourceIn.mock.calls.at(-1)![1]).not.toBe(first[1]) + expect(b.openResource.mock.calls.at(-1)![0]).not.toBe(first[0]) expect(b.slots.entries('sidebar.right.pane.tab')[0]!.component).toBe(PlanPreview) expect(b.slots.entries('sidebar.right.pane.tab.title')[0]!.component).toBe(PlanTitle) await fiber.dispose() diff --git a/packages/client/ui-renderer/src/client/registry.ts b/packages/client/ui-renderer/src/client/registry.ts index 94cbcee427..ea3891b65f 100644 --- a/packages/client/ui-renderer/src/client/registry.ts +++ b/packages/client/ui-renderer/src/client/registry.ts @@ -352,16 +352,17 @@ export class SlotRegistry extends Service { } /** - * Bind scoped Store instances to one owner Context lifetime. Cleanup drops - * only materialized in-memory instances; persisted state belongs to the - * durable scope key. Rebinding the same key transfers cleanup ownership to - * the newest Context generation. + * Bind scoped Store instances to one Context generation. Rebinding the key + * drops the previous generation's memory instances before the new owner can + * resolve them. Cleanup never clears persisted state, which belongs to the + * durable scope key, or drops a replacement generation's instances. * * @param binding - materialized scope identity and its owning Context. */ bindStoreScope(binding: Pick): void { const current = this._storeScopeOwners.get(binding.key) if (current === binding.ctx) return + if (current !== undefined) this.releaseStoreScope(binding.key) this._storeScopeOwners.set(binding.key, binding.ctx) binding.ctx.effect(() => () => { if (this._storeScopeOwners.get(binding.key) !== binding.ctx) return diff --git a/packages/client/ui-renderer/tests/registry.client.spec.ts b/packages/client/ui-renderer/tests/registry.client.spec.ts index bc85bcf19e..1db77dd05f 100644 --- a/packages/client/ui-renderer/tests/registry.client.spec.ts +++ b/packages/client/ui-renderer/tests/registry.client.spec.ts @@ -764,6 +764,56 @@ describe('store instance axis', () => { await replacement.fiber.dispose() }) + it.each(['t.panel', 't.maybe'] as const)('separates %s memory when a Session reopens before previous Context cleanup', async (slot) => { + const { bench, host } = await storeBench() + const persisted = new Map() + const clearPersisted = vi.fn() + const handle = { + create: vi.fn((scopeKey?: string) => { + const key = scopeKey ?? 'root' + let expanded = false + let saved = persisted.get(key) ?? 0 + return { + getSnapshot: () => ({ expanded, saved }), + subscribe: () => () => {}, + actions: { + expand: () => { expanded = true }, + save: (value: number) => { saved = value; persisted.set(key, value) }, + }, + clearPersisted, + } + }), + } + bench.erased.register({ name: slot, store: handle }, C) + const [entry] = host.entriesOf(slot) + const first = scopedBinding(bench.ctx, 's1') + const other = scopedBinding(bench.ctx, 's2') + const replacement = scopedBinding(bench.ctx, 's1') + try { + const before = host.storeOf(entry as never, first.binding) as ReturnType + before.actions.expand() + before.actions.save(7) + const unaffected = host.storeOf(entry as never, other.binding) as ReturnType + unaffected.actions.expand() + const after = host.storeOf(entry as never, replacement.binding) as ReturnType + expect(after).not.toBe(before) + expect(after.getSnapshot()).toEqual({ expanded: false, saved: 7 }) + expect(handle.create.mock.calls.map(([key]) => key)).toEqual(['s1', 's2', 's1']) + expect(host.storeOf(entry as never, other.binding)).toBe(unaffected) + expect(unaffected.getSnapshot().expanded).toBe(true) + after.actions.expand() + after.actions.save(9) + await first.fiber.dispose() + expect(host.storeOf(entry as never, replacement.binding)).toBe(after) + expect(after.getSnapshot()).toEqual({ expanded: true, saved: 9 }) + expect(persisted.get('s1')).toBe(9) + expect(clearPersisted).not.toHaveBeenCalled() + } finally { + await Promise.all([first.fiber.dispose(), replacement.fiber.dispose(), other.fiber.dispose()]) + await bench.ctx.fiber.dispose() + } + }) + it('does not materialize scoped stores solely for scope release', async () => { const { bench } = await storeBench() const root = fakeHandle() diff --git a/packages/client/ui-session/README.i18n.yaml b/packages/client/ui-session/README.i18n.yaml index eec5a1a51f..03b356e547 100644 --- a/packages/client/ui-session/README.i18n.yaml +++ b/packages/client/ui-session/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-session/README.md -README.md: 4fff368e58d7b422ba6948be78e543c31f5cef59 -README.zh.md: db37539b59231bfef50f3bdcc33aeae94e881a44 +README.md: 22ece0c11eee6b2a59acbbd8c5a9650b593a7da4 +README.zh.md: 4b52bef28ad065a7ff10f468056723c4d301a0a0 diff --git a/packages/client/ui-session/README.md b/packages/client/ui-session/README.md index 4fff368e58..22ece0c11e 100644 --- a/packages/client/ui-session/README.md +++ b/packages/client/ui-session/README.md @@ -10,6 +10,8 @@ English | [中文](README.zh.md) Use this package to expose Session catalog, retain information, and unified UI status through standard Slot hooks. It materializes per-`SessionBinding` hooks and props, while `SessionProvider` can inherit an outer binding or bind an explicit `SessionReference`. It owns process-local pending-interaction and completion-reminder policy without owning Controller transport, history, or references. +Running status comes from Host list baselines or status events. Catalog rows and local fallback rows do not establish running status; main view references still acknowledge completions. + ## Table of Contents - [Model Experience](#model-experience) diff --git a/packages/client/ui-session/README.zh.md b/packages/client/ui-session/README.zh.md index db37539b59..4b52bef28a 100644 --- a/packages/client/ui-session/README.zh.md +++ b/packages/client/ui-session/README.zh.md @@ -10,6 +10,8 @@ kind: "package-reference" 使用本包可通过标准 Slot 钩子公开 Session catalog、retain 信息与统一 UI 状态。它按 `SessionBinding` 物化钩子和 prop,而 `SessionProvider` 可以继承外围 binding 或绑定显式 `SessionReference`。它拥有进程本地的 pending-interaction 与完成提醒策略,但不拥有 Controller transport、历史或 reference。 +运行状态来自 Host 列表基线或状态事件。目录和保留代际的 fallback 行不会建立运行状态;主视图引用仍会确认完成提醒。 + ## 目录 - [模型体验](#model-experience) diff --git a/packages/client/ui-session/package.json b/packages/client/ui-session/package.json index ac006223f5..3420171409 100644 --- a/packages/client/ui-session/package.json +++ b/packages/client/ui-session/package.json @@ -48,8 +48,10 @@ "@deepseek-ai/dsh-api-remotes": "workspace:^", "@deepseek-ai/dsh-api-session-controller": "workspace:^", "@deepseek-ai/dsh-client-store": "workspace:^", + "@deepseek-ai/dsh-client-test-runtime": "workspace:^", "@deepseek-ai/dsh-client-ui-renderer": "workspace:^", "@deepseek-ai/dsh-client-ui-slots": "workspace:^", + "@deepseek-ai/dsh-remote-mock": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-util-values": "workspace:^", "@types/react": "~18.3.1", diff --git a/packages/client/ui-session/src/client/index.ts b/packages/client/ui-session/src/client/index.ts index 5e3285bbd0..1f94bce4bb 100644 --- a/packages/client/ui-session/src/client/index.ts +++ b/packages/client/ui-session/src/client/index.ts @@ -7,6 +7,7 @@ import type { SessionReference, SessionRetainInfo, SessionSnapshot, + SessionSummary, UseProjection, } from '@deepseek-ai/dsh-api-session-controller/client' import type { SessionId } from '@deepseek-ai/dsh-session/types' @@ -492,13 +493,15 @@ export class UiSession extends Service { private reconcileStatus(): void { const list = this.sessions.list.getSnapshot() const present = new Set(Object.keys(list.byId) as SessionId[]) - for (const id of present) { - const row = list.byId[id] - if (row === undefined) continue + // Rows from catalogs and retained Client bindings do not establish Host running state. + for (const id of list.ids) { + const row = list.byId[id] as SessionSummary const previous = this.running.get(id) if (previous === undefined) this.running.set(id, row.running) else if (previous !== row.running) this.observeRunning(id, row.running) - if ((row.retainedBy.mainView ?? 0) > 0) this.completionUnread.delete(id) + } + for (const id of present) { + if (this.isMain(id)) this.completionUnread.delete(id) } if (list.phase === 'ready') { for (const id of this.running.keys()) { diff --git a/packages/client/ui-session/tests/status-controller.client.spec.ts b/packages/client/ui-session/tests/status-controller.client.spec.ts new file mode 100644 index 0000000000..1bf3bfec88 --- /dev/null +++ b/packages/client/ui-session/tests/status-controller.client.spec.ts @@ -0,0 +1,64 @@ +/** Running-state ownership across the real Controller catalog and UI status source. */ +import { expect, vi } from 'vitest' +import { ok } from '@deepseek-ai/dsh-remote-mock' +import { createClientTest, webApp } from '@deepseek-ai/dsh-client-test-runtime/src/assembly/index.ts' +import { SESSION_FORMAT_VERSION, type SessionId } from '@deepseek-ai/dsh-session/types' +import type { SessionFollowFrame } from '@deepseek-ai/dsh-api-session-controller/types' + +const it = createClientTest({ roster: webApp.closure(['@deepseek-ai/dsh-client-ui-session']) }) +const parentId = 'status-parent' as SessionId +const childId = 'status-child' as SessionId + +it('preserves unlisted child status through metadata updates and main view acknowledgement', async ({ mock, start }) => { + mock.remote.session.list.mockResolvedValue(ok({ items: [{ + sessionId: parentId, updatedAt: 1, running: false, blank: false, agentAvailable: true, + }] })) + mock.remote.session.projections.mockResolvedValue(ok({ + asOfSeq: 0, + values: { subagentCatalog: [{ id: childId, createdAt: 1, mode: 'continuable', label: 'Child' }] }, + })) + mock.stream('session/follow', (_request, stream) => { + stream.push({ + type: 'snapshot', + header: { version: SESSION_FORMAT_VERSION, id: childId, createdAt: 1, isSeeded: false, + parentSession: parentId, origin: 'subagent' }, + cursor: -1, records: [], hasMore: false, + projections: { asOfSeq: -1, values: {} }, assistantStream: { revision: 0 }, + } satisfies SessionFollowFrame) + }) + const client = await start() + const sessions = client.ctx.sessions + const ui = client.ctx.uiSession + await sessions.refresh() + await sessions.refreshProjections(parentId) + await client.flush() + expect(sessions.list.getSnapshot().ids).toEqual([parentId]) + expect(sessions.binding(childId)).toBeUndefined() + expect(ui.sessionStatus.getSnapshot().get(childId)).toMatchObject({ running: undefined, completionUnread: false }) + + mock.streams.push('$events', { type: 'emit', event: 'api-session/status', args: [childId, true] }) + await mock.streams.drained('$events') + await client.flush() + expect(ui.sessionStatus.getSnapshot().get(childId)).toMatchObject({ running: true, completionUnread: false }) + + mock.streams.push('$events', { type: 'emit', event: 'api-session/activity', args: [parentId, 2] }) + await mock.streams.drained('$events') + await client.flush() + expect(sessions.list.getSnapshot().byId[parentId]?.updatedAt).toBe(2) + expect(ui.sessionStatus.getSnapshot().get(childId)).toMatchObject({ running: true, completionUnread: false }) + + mock.streams.push('$events', { type: 'emit', event: 'api-session/status', args: [childId, false] }) + await mock.streams.drained('$events') + await client.flush() + expect(ui.sessionStatus.getSnapshot().get(childId)).toMatchObject({ running: false, completionUnread: true }) + + using reference = sessions.retain(childId, { source: 'mainView' }) + await reference.ready + expect(sessions.list.getSnapshot().ids).not.toContain(childId) + await vi.waitFor(() => { + expect(ui.sessionStatus.getSnapshot().get(childId)).toMatchObject({ running: false, completionUnread: false }) + }) + reference.release() + await client.flush() + expect(ui.sessionStatus.getSnapshot().get(childId)?.completionUnread).toBe(false) +}) diff --git a/packages/client/ui-session/tests/ui-session.client.spec.ts b/packages/client/ui-session/tests/ui-session.client.spec.ts index bce5fdadcc..e9c80918bd 100644 --- a/packages/client/ui-session/tests/ui-session.client.spec.ts +++ b/packages/client/ui-session/tests/ui-session.client.spec.ts @@ -53,7 +53,7 @@ function createSessionsBench(ctx: Context): SessionsBench { ids: [], byId: {}, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, }) const bindings = new Map() @@ -522,6 +522,27 @@ describe('UiSession bindings', () => { }) describe('UiSession status', () => { + it('keeps synthetic-row status unknown until an event or Host baseline establishes it', () => { + const ctx = new Context() + const bench = createSessionsBench(ctx) + const id = sessionId('catalog-only') + bench.list.update((draft) => { + draft.byId[id] = { id, displayTitle: id, running: false, retainedBy: {}, blank: false, updatedAt: 0 } + }) + const service = createUiSession(ctx, bench) + expect(service.sessionStatus.getSnapshot().get(id)?.running).toBeUndefined() + expect(service.sessionStatus.getSnapshot().get(id)?.completionUnread).toBe(false) + + bench.emitStatus(id, true) + bench.list.update((draft) => { draft.byId[id]!.displayTitle = 'Renamed child' }) + expect(service.sessionStatus.getSnapshot().get(id)?.running).toBe(true) + expect(service.sessionStatus.getSnapshot().get(id)?.completionUnread).toBe(false) + + bench.list.update((draft) => { draft.ids.push(id) }) + expect(service.sessionStatus.getSnapshot().get(id)?.running).toBe(false) + expect(service.sessionStatus.getSnapshot().get(id)?.completionUnread).toBe(true) + }) + it('records non-main completions and lets main-view activity acknowledge them', () => { const ctx = new Context() const bench = createSessionsBench(ctx) diff --git a/packages/client/ui-settings-general/tests/settings-root.client.spec.tsx b/packages/client/ui-settings-general/tests/settings-root.client.spec.tsx index 34c20283df..74a5b22cfb 100644 --- a/packages/client/ui-settings-general/tests/settings-root.client.spec.tsx +++ b/packages/client/ui-settings-general/tests/settings-root.client.spec.tsx @@ -88,7 +88,7 @@ function mount({ updatedAt: 0, }, }, - phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + phase: 'ready', projectionsBySession: {}, jobsBySession: {}, } const unusedHook = (() => { throw new Error('unused by SettingsRoot') }) as never const props: SettingsRootComponentProps = { diff --git a/packages/client/ui-sidebar-right/README.i18n.yaml b/packages/client/ui-sidebar-right/README.i18n.yaml index 4de8cd03f3..8cfd6b578a 100644 --- a/packages/client/ui-sidebar-right/README.i18n.yaml +++ b/packages/client/ui-sidebar-right/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-sidebar-right/README.md -README.md: dbe09becc8f5f322720c21f89e5042a1f423e6f0 -README.zh.md: 357f9366298dcc4313068d78f73105691d82c129 +README.md: e9c143f34076c308f3afdb348cc09506f3983a35 +README.zh.md: 72d0c20817c690c1dcca5a97b67adbdfa1f11261 diff --git a/packages/client/ui-sidebar-right/README.md b/packages/client/ui-sidebar-right/README.md index dbe09becc8..e9c143f340 100644 --- a/packages/client/ui-sidebar-right/README.md +++ b/packages/client/ui-sidebar-right/README.md @@ -97,7 +97,7 @@ Two more seats extend what is already there: `sidebar.right.tab.guide` (chain) r ## The Tab domain -The Tab domain retains navigation, an abort signal, and bound actions per (Session, tab id). A private assembly callback adopts each Session's store, reconciles restored records immediately, and follows its commits. Only record removal or plugin unload aborts the signal; closing the sidebar and switching Sessions retain records, while undo restores a new occurrence. `useTabInfo()` composes framework-bound store and navigation hooks without manual component subscriptions or render-time record creation. `tab.actions` always target their own Session; `tab.visible` distinguishes bodies from titles, and floating tabs remain visible when the sidebar closes. `adopt` is absent from the public controller. +The Tab domain retains navigation, an abort signal, and bound actions per (Session, tab id). A private assembly callback adopts each Session's store, reconciles restored records immediately, and follows its commits. Reconstructing a Session store replaces its adoption, releasing the old subscription and cleanup reference. Only record removal or plugin unload aborts the signal; closing the sidebar and switching Sessions retain records, while undo restores a new occurrence. `useTabInfo()` composes framework-bound store and navigation hooks without manual component subscriptions or render-time record creation. `tab.actions` always target their own Session; `tab.visible` distinguishes bodies from titles, and floating tabs remain visible when the sidebar closes. `adopt` is absent from the public controller. Tab owners register `registerCloseHandler(kind, handler)` through an effect. A handler synchronously retains any background cleanup before allowing explicit close or replacement. The resource owner tracks completion and retry; the sidebar does not wait. A thrown handler preserves the tab. Collapse, presentation changes and plugin disposal do not invoke close handlers; the tab abort signal identifies occurrence disposal, not an explicit close. diff --git a/packages/client/ui-sidebar-right/README.zh.md b/packages/client/ui-sidebar-right/README.zh.md index 357f936629..72d0c20817 100644 --- a/packages/client/ui-sidebar-right/README.zh.md +++ b/packages/client/ui-sidebar-right/README.zh.md @@ -97,7 +97,7 @@ tab 类型分两阶段注册,随包发布的引导类型走的正是别的包 ## Tab 域 -Tab 域按(Session,Tab id)保留导航、中止信号与绑定动作。私有装配回调采用各 Session 的 store,立即对齐恢复的记录,再跟随其提交。记录消失或插件卸载才中止 signal,收起和切会话不销毁记录;undo 恢复的是新 occurrence。`useTabInfo()` 组合框架绑定的 store 与导航 hook,不在组件中手写订阅或在渲染时创建记录。`tab.actions` 始终作用于自己的会话;`tab.visible` 区分正文与标题,浮窗不受整栏收起影响。`adopt` 不在公开控制器上。 +Tab 域按(Session,Tab id)保留导航、中止信号与绑定动作。私有装配回调采用各 Session 的 store,立即对齐恢复的记录,再跟随其提交。同一 Session 的 store 重建会替换其 `adopt` 注册,同时释放旧订阅与清理引用。记录消失或插件卸载才中止 signal,收起和切会话不销毁记录;undo 恢复的是新 occurrence。`useTabInfo()` 组合框架绑定的 store 与导航 hook,不在组件中手写订阅或在渲染时创建记录。`tab.actions` 始终作用于自己的会话;`tab.visible` 区分正文与标题,浮窗不受整栏收起影响。`adopt` 不在公开控制器上。 标签页所有者通过 effect 注册 `registerCloseHandler(kind, handler)`。handler 在允许显式关闭或替换前同步保存后台清理任务。资源所有者跟踪完成和重试,侧栏不等待清理。handler 抛错时保留标签页。折叠、展示方式改变和插件卸载不调用关闭 handler;tab abort signal 标识 occurrence 卸载,不代表显式关闭。 diff --git a/packages/client/ui-sidebar-right/src/client/index.ts b/packages/client/ui-sidebar-right/src/client/index.ts index f4131a7031..c50c757f23 100644 --- a/packages/client/ui-sidebar-right/src/client/index.ts +++ b/packages/client/ui-sidebar-right/src/client/index.ts @@ -122,16 +122,18 @@ export function apply(ctx: ClientContext): void { ctx.effect(() => { const handle = createSidebarRightStore(() => defaultSeed(tabs)) - // The runtime mints one instance of this handle per session (the scope key - // is the session id) and caches it per key. Each is adopted as it is minted, - // so a tab's own action reaches its session's store while another session - // is on screen, and that store's commits sync the Tab domain themselves. - const adoptions: Array<() => void> = [] + // Each Session Context generation owns one Store. Background tab actions + // use the latest adoption for that Session. + const adoptions = new Map void>() const store: typeof handle = { ...handle, create: (scopeKey) => { const instance = handle.create(scopeKey) - if (scopeKey !== undefined) adoptions.push(adopt(scopeKey as SessionId, instance)) + if (scopeKey !== undefined) { + const sessionId = scopeKey as SessionId + adoptions.get(sessionId)?.() + adoptions.set(sessionId, adopt(sessionId, instance)) + } return { ...instance, clearPersisted() { instance.clearPersisted() if (scopeKey !== undefined) forget(scopeKey as SessionId) @@ -212,7 +214,8 @@ export function apply(ctx: ClientContext): void { disposeExpand() disposeSeat() for (const dispose of disposeTypes.reverse()) dispose() - for (const release of adoptions) release() + for (const release of adoptions.values()) release() + adoptions.clear() } }, 'ui-sidebar-right: seats and shipped tab type') } diff --git a/packages/client/ui-sidebar-right/tests/apply.client.spec.ts b/packages/client/ui-sidebar-right/tests/apply.client.spec.ts index 6afbbd8235..530334eae2 100644 --- a/packages/client/ui-sidebar-right/tests/apply.client.spec.ts +++ b/packages/client/ui-sidebar-right/tests/apply.client.spec.ts @@ -18,6 +18,7 @@ import { apply as hostApply } from '../src/index.ts' import { SidebarRightController } from '../src/client/service.ts' import { SidebarRightTabRegistry } from '../src/client/tab-registry.ts' import type { createSidebarRightStore } from '../src/client/stores.ts' +import * as sidebarStores from '../src/client/stores.ts' import { RightbarSeat } from '../src/client/shell/SidebarRight.tsx' import { RightbarRoot } from '../src/client/shell/RightbarRoot.tsx' import { ExpandButton } from '../src/client/shell/ExpandButton.tsx' @@ -173,6 +174,50 @@ describe('ui-sidebar-right apply', () => { expect(ctx.sidebarRight.openTabs.getSnapshot()).toEqual([]) }) + it('releases replaced store adoptions once and keeps the latest store for each Session', async () => { + const originalFactory = sidebarStores.createSidebarRightStore + const stops: Array void>>> = [] + const factory = vi.spyOn(sidebarStores, 'createSidebarRightStore').mockImplementation((seed) => { + const handle = originalFactory(seed) + return { + ...handle, + create(scopeKey) { + const instance = handle.create(scopeKey) + return { + ...instance, + subscribe(listener) { + const stop = vi.fn(instance.subscribe(listener)) + stops.push(stop) + return stop + }, + } + }, + } + }) + let b: Awaited> | undefined + try { + b = await boot() + const handle = b.seat('rightbar.session').store as ReturnType + const other = 's-other' as SessionId + handle.create(SESSION) + handle.create(other) + handle.create(SESSION) + handle.create(other) + const current = handle.create(SESSION) + const currentOther = handle.create(other) + expect(stops.map(stop => stop.mock.calls.length)).toEqual([1, 1, 1, 1, 0, 0]) + current.actions.setExpanded(SESSION, true) + currentOther.actions.setExpanded(other, true) + expect(new Set(b.ctx.sidebarRight.openTabs.getSnapshot().map(tab => tab.sessionId))) + .toEqual(new Set([SESSION, other])) + await b.fiber.dispose() + expect(stops.map(stop => stop.mock.calls.length)).toEqual([1, 1, 1, 1, 1, 1]) + } finally { + await b?.ctx.fiber.dispose() + factory.mockRestore() + } + }) + it('hands the guide body the registry\'s entry boxes, observable', async () => { const { ctx, seat, injectedOf } = await boot() const { hooks: { guideEntries } } = injectedOf(seat('sidebar.right.pane.tab')) as GuideInjected diff --git a/packages/client/ui-subagent/README.i18n.yaml b/packages/client/ui-subagent/README.i18n.yaml index a36e5f58be..45a496719c 100644 --- a/packages/client/ui-subagent/README.i18n.yaml +++ b/packages/client/ui-subagent/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-subagent/README.md -README.md: 136829a6f5ea7f40e291f913651cd98adac9d916 -README.zh.md: 9a4633d7ba3b6c66527ec79f5850f42b1ec2a449 +README.md: 1404e893add386b88a24d78675a4f0be06f497a0 +README.zh.md: 97c743b580e25cd50bcb01a3a7547cb7415a0e08 diff --git a/packages/client/ui-subagent/README.md b/packages/client/ui-subagent/README.md index 136829a6f5..1404e893ad 100644 --- a/packages/client/ui-subagent/README.md +++ b/packages/client/ui-subagent/README.md @@ -25,13 +25,13 @@ Use this package to browse every subagent conversation beneath a parent session, ## Use this package -The session header keeps the current session title as the lineage breadcrumb and, when the session has subagent descendants, appends a `/` count trigger before the header's action row; the trigger opens the descendant catalog, counts the complete subagent-only lineage, stops at ordinary forks, and shows ongoing activity when any counted descendant is running. Select any depth to open that child's conversation with its exact `{parentSessionId, childSessionId, mode}` address, or use the row's trailing arrow to open the same address in the right Sidebar, preferring a separate pane when room permits. +The session header keeps the current session title as the lineage breadcrumb and appends a `/` count trigger when its direct catalog has entries or a read has failed. An absent catalog, an empty loading catalog, or a successfully loaded empty catalog hides the count trigger. The trigger opens that direct catalog, reports its total and running counts, and loads nested catalogs only when their rows expand. Select any depth to open that child's conversation with its exact `{parentSessionId, childSessionId, mode}` address, or use the row's trailing arrow to open the same address in the right Sidebar, preferring a separate pane when room permits. This package registers the `dsh-resource://subagentchat/session/?parent=&mode=` resource and builtin Sidebar tab type. The resource refreshes the direct-parent catalog before it retains the child `SessionReference`, and releases the reference when the tab record closes. The tab renders the shared `conversation.content` Factory through `sidebar.chat.conversation`, fixes the local View to Chat, and omits the main Conversation header and width controls. ### Browsing the tree -Rows display mode plus activity and an optional log-backed title; running uses the shared ongoing loader, an inactive child whose latest closed turn completed normally uses the shared success dot, other inactive children use the shared idle dot, and diagnostic rows use the shared error dot. Every row reserves the same 14px status column, centering smaller dots so titles align with the loader state. The compact header trigger vertically centers its activity glyph and count with a 4px gap. The trailing column stacks total durable provider usage above active-turn duration. Keyboard navigation works with ArrowRight/ArrowLeft to expand and collapse branches and ArrowUp/ArrowDown, Home, End, and Escape to navigate or close the tree. An unlabeled one-shot row falls back to its session id; corrupt, unsupported, or unavailable rows remain readable but disabled. +Rows display mode plus activity and an optional log-backed title; running uses the shared ongoing loader, an inactive child whose latest closed turn completed normally uses the shared success dot, and other inactive children use the shared idle dot. Every row reserves the same 14px status column, centering smaller dots so titles align with the loader state. The compact header trigger vertically centers its activity glyph and count with a 4px gap. The trailing column stacks total durable provider usage above active-turn duration. Keyboard navigation works with ArrowRight/ArrowLeft to expand and collapse branches and ArrowUp/ArrowDown, Home, End, and Escape to navigate or close the tree. An unlabeled one-shot row falls back to its session id. A row is a known leaf only after its own catalog loads empty. ### Continuing a conversation @@ -53,11 +53,13 @@ The catalog and composer behavior are specified by the [Web subagent conversatio ### Catalog derivation -The header lineage renderer reads `subagentsByParent` and session summaries through the standard `useSessions` hook. The compact tree remains direct-catalog authoritative: each healthy row's `hasChildren` hint determines disclosure before interaction, a catalog level reserves the disclosure column only when at least one healthy row is a branch, and expanding a branch immediately reserves one disabled loading row per known direct descendant before lazily replacing them with that child's authoritative catalog. Every visible branch is reported to the runtime so membership frames cause a debounced refresh only where the tree is being consumed. +The header lineage renderer reads `projectionsBySession` through the standard `useSessions` hook. The renderer selects `subagentCatalog` from each Session’s shared values for membership, disclosure, and counts; Activity prefers the unified UI status and falls back to Session summaries; summaries supply titles and usage. Expanding a row loads its initial catalog when needed. Live projection frames update every loaded level without menu subscriptions or repeated membership queries. A row remains expandable while its catalog is absent, loading, or failed, and becomes a known leaf after a ready empty catalog. + +Breadcrumb addresses derive from the Provider-bound Session address and loaded parent catalogs, including never-selected ancestors. ### Duration, completion, and tokens -Token totals sum the four disjoint `tokenUsage` buckets. The `subagentTiming` projection sums completed-turn duration and records whether the latest closed turn ended with `completed`; opening another turn clears that completion until its own `turn/end`. Duration advances once per second only for an open turn on a running child and freezes after the child becomes inactive; an interrupted open turn is bounded by its same-cut `active.through`, never by newer session metadata. +Each visible catalog level advances its own clock while it contains a running child; collapsing the level or closing the menu releases that clock. Token totals sum the four disjoint `tokenUsage` buckets. The `subagentTiming` projection sums completed-turn duration and records whether the latest closed turn ended with `completed`; opening another turn clears that completion until its own `turn/end`. Duration advances once per second only for an open turn on a running child and freezes after the child becomes inactive; an interrupted open turn is bounded by its same-cut `active.through`, never by newer session metadata. ### Composer election diff --git a/packages/client/ui-subagent/README.zh.md b/packages/client/ui-subagent/README.zh.md index 9a4633d7ba..97c743b580 100644 --- a/packages/client/ui-subagent/README.zh.md +++ b/packages/client/ui-subagent/README.zh.md @@ -25,13 +25,13 @@ kind: "package-reference" ## 使用本包 -会话页头保留当前会话 title 作为谱系面包屑,并在会话存在 subagent 后代时,于页头操作行之前追加 `/` 数量触发器;触发器打开后代目录,统计仅含 subagent 的完整谱系、在普通 fork 处停止,并在任一计入统计的后代处于 `running` 时显示活动仍在进行。选择任意深度,即可用该子会话的确切 `{parentSessionId, childSessionId, mode}` 地址打开其对话;也可以使用行尾箭头在右侧 Sidebar 打开同一地址,并在空间允许时优先使用独立分栏。 +会话页头保留当前会话 title 作为谱系面包屑,并在直接目录有子项或读取失败时追加 `/` 数量触发器。目录缺席、空目录加载中或成功加载为空时,均隐藏数量触发器。触发器打开该直接目录,报告总数与运行数,并且只在行展开时加载嵌套目录。选择任意深度,即可用该子会话的确切 `{parentSessionId, childSessionId, mode}` 地址打开其对话;也可以使用行尾箭头在右侧 Sidebar 打开同一地址,并在空间允许时优先使用独立分栏。 本包注册 `dsh-resource://subagentchat/session/?parent=&mode=` 资源与 builtin Sidebar tab 类型。资源先刷新直接 parent 目录,再保留 child 的 `SessionReference`,并在 tab 记录关闭时释放 reference。tab 通过 `sidebar.chat.conversation` 渲染共享 `conversation.content` Factory,把局部 View 固定为 Chat,并省略主 Conversation 的 Header 与宽度控制。 ### 浏览目录 -行显示 mode、活动状态与由日志支撑的可选 title;running 使用共享 ongoing loading,最近一个已结束轮次正常完成的 inactive child 使用共享 success 绿点,其他 inactive child 使用共享 idle 灰点,诊断行使用共享 error 红点。每行都为状态图标预留相同的 14px 列宽,并将较小的圆点居中,使 title 与 loading 状态对齐。紧凑的页头触发器会垂直居中活动图标与数量,并保留 4px 水平间距。尾随列在上行显示提供方的持久化 token 用量总计,在下行显示活跃轮次耗时。键盘导航:ArrowRight/ArrowLeft 展开和折叠分支;ArrowUp/ArrowDown、Home、End 与 Escape 用于导航或关闭树。没有 label 的 one-shot 行回退到其会话 id;损坏、不受支持或不可用的行仍保持可读但禁用。 +行显示 mode、活动状态与由日志支撑的可选 title;running 使用共享 ongoing loading,最近一个已结束轮次正常完成的 inactive child 使用共享 success 绿点,其他 inactive child 使用共享 idle 灰点。每行都为状态图标预留相同的 14px 列宽,并将较小的圆点居中,使 title 与 loading 状态对齐。紧凑的页头触发器会垂直居中活动图标与数量,并保留 4px 水平间距。尾随列在上行显示提供方的持久化 token 用量总计,在下行显示活跃轮次耗时。键盘导航:ArrowRight/ArrowLeft 展开和折叠分支;ArrowUp/ArrowDown、Home、End 与 Escape 用于导航或关闭树。没有 label 的 one-shot 行回退到其会话 id。只有一行自身的目录加载为空后,它才是已知叶子。 ### 续接对话 @@ -53,11 +53,13 @@ kind: "package-reference" ### 目录派生 -页头谱系 renderer 通过标准 `useSessions` 钩子读取 `subagentsByParent` 与会话摘要。紧凑树仍以直接目录为权威依据:每个健康行的 `hasChildren` 提示在交互前决定是否显示展开控件;每层目录仅在其中至少一个健康行是分支时才预留展开列;展开分支时会立即为每个已知直接后代预留一行禁用的加载行,随后再用该 child 的权威目录懒加载结果替换。每个可见分支都会上报给运行时,使成员帧只在树正被消费的位置触发去抖动刷新。 +页头谱系 renderer 通过标准 `useSessions` 钩子读取 `projectionsBySession`。renderer 从每个 Session 的共享值中选择 `subagentCatalog`,用于成员关系、展开控件与数量;活动状态优先使用统一 UI status,缺少时使用 Session 摘要;摘要提供标题与用量。展开行会按需加载初始目录。实时 projection 帧更新所有已加载层级,无需菜单订阅或重复成员查询。行在目录缺席、加载中或失败时保持可展开,并在目录就绪且为空后成为已知叶子。 + +面包屑地址从 Provider 所绑定的 Session 地址和已加载的 parent 目录推导,也包括从未选中过的祖先。 ### 耗时、完成状态与 token -token 用量总计为四个互不重叠的 `tokenUsage` 桶之和。`subagentTiming` 投影会累加已结束轮次的耗时,并记录最近一个已结束轮次是否以 `completed` 结束;新轮次开始时会清除该完成状态,直到自身的 `turn/end` 到达。耗时仅在运行中 child 存在未结束轮次时每秒递增一次,并在 child 变为 inactive 后冻结;被中断的未结束轮次以其同一切面的 `active.through` 为上界,绝不使用更新的会话元数据。 +每个可见目录层在包含运行中 child 时独立推进时钟;折叠该层或关闭菜单会释放时钟。token 用量总计为四个互不重叠的 `tokenUsage` 桶之和。`subagentTiming` 投影会累加已结束轮次的耗时,并记录最近一个已结束轮次是否以 `completed` 结束;新轮次开始时会清除该完成状态,直到自身的 `turn/end` 到达。耗时仅在运行中 child 存在未结束轮次时每秒递增一次,并在 child 变为 inactive 后冻结;被中断的未结束轮次以其同一切面的 `active.through` 为上界,绝不使用更新的会话元数据。 ### 编辑器选举 diff --git a/packages/client/ui-subagent/src/client/SubagentHeaderLineage.module.css b/packages/client/ui-subagent/src/client/SubagentHeaderLineage.module.css index 6563066ff4..b9a28a3781 100644 --- a/packages/client/ui-subagent/src/client/SubagentHeaderLineage.module.css +++ b/packages/client/ui-subagent/src/client/SubagentHeaderLineage.module.css @@ -169,19 +169,6 @@ height: 17px; } -.disabled { - color: var(--dsw-alias-label-dimmed); - cursor: not-allowed; -} - -.disabled:hover { - background: transparent; -} - -.loadingRow { - cursor: default; -} - .disclosure, .disclosureSpace { flex: none; diff --git a/packages/client/ui-subagent/src/client/SubagentHeaderLineage.tsx b/packages/client/ui-subagent/src/client/SubagentHeaderLineage.tsx index 714398f075..6dd416fb95 100644 --- a/packages/client/ui-subagent/src/client/SubagentHeaderLineage.tsx +++ b/packages/client/ui-subagent/src/client/SubagentHeaderLineage.tsx @@ -1,10 +1,8 @@ -import { - useEffect, useMemo, useRef, useState, type CSSProperties, type KeyboardEvent, type MouseEvent, -} from 'react' +import { useMemo, useEffect, useRef, useState, type CSSProperties, type KeyboardEvent, type MouseEvent } from 'react' import { createPortal } from 'react-dom' import { - type SessionListState, type SessionProjectionMap, type SessionSummary, - type SubagentCatalogSnapshot, + type SessionProjectionMap, type SessionSummary, + type SessionProjectionSnapshot, } from '@deepseek-ai/dsh-api-session-controller/client' import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client' import type { SessionId } from '@deepseek-ai/dsh-session/types' @@ -16,17 +14,18 @@ import { NS } from './locales.ts' import type {} from '@deepseek-ai/dsh-client-ui-conversation/client' import type {} from '@deepseek-ai/dsh-token-meter/client' import css from './SubagentHeaderLineage.module.css' -import { indexSubagentDescendants } from './subagent-lineage.ts' -type CatalogEntry = SubagentCatalogSnapshot['entries'][number] -type Catalogs = SessionListState['subagentsByParent'] +type SubagentCatalogSnapshot = Omit & { + state: 'loading' | 'ready' | 'error' + entries: (SessionProjectionMap['subagentCatalog'][number] & { activity: 'running' | 'inactive' })[] +} +type Catalogs = Readonly> /** Business actions supplied by the slot registration. */ export interface SubagentCatalogInjected { openChild: (address: SubagentAddress) => void openChildAside: (address: SubagentAddress) => void refresh: (parentSessionId: SessionId) => void - setCatalogOpen: (parentSessionId: SessionId, open: boolean) => void } /** Full props for the session-header lineage renderer. */ @@ -41,7 +40,6 @@ interface CatalogRowsProps { summaries: Readonly> expanded: ReadonlySet level: number - now: number openChild: (address: SubagentAddress) => void openChildAside: (address: SubagentAddress) => void refresh: (parentSessionId: SessionId) => void @@ -49,17 +47,6 @@ interface CatalogRowsProps { closeCatalog: () => void } -function diagnosticReason( - entry: Extract, - t: TranslateNS, -): string { - switch (entry.reason) { - case 'corrupt': return t('diagnostic.corrupt') - case 'unsupported': return t('diagnostic.unsupported') - case 'unavailable': return t('diagnostic.unavailable') - } -} - function treeItems(root: HTMLDivElement | null): HTMLElement[] { return root === null ? [] @@ -177,8 +164,6 @@ function formatExactDuration(ms: number, t: TranslateNS): string { }) } -const NO_DESCENDANTS = { count: 0, runningCount: 0 } as const - function SubagentSwitcherIcon() { return ( > - level: number - t: TranslateNS -}) { - const children = Object.values(summaries).filter(summary => ( - summary.origin === 'subagent' && summary.parentId === parentSessionId - )) - if (children.length === 0) return

{t('loading.label')}
- return children.map(summary => ( -
-
- - - - - - {t('loading.label')} - -
-
- )) +/** Render catalog loading without inventing child membership. */ +function CatalogLoadingRows({ t }: { t: TranslateNS }) { + return
{t('loading.label')}
+} + +/** A child becomes a known leaf only after its own authoritative catalog loads empty. */ +function isKnownLeaf(catalog: SubagentCatalogSnapshot | undefined): boolean { + return catalog?.state === 'ready' && catalog.entries.length === 0 } /** Render one catalog level and recurse only through explicitly expanded rows. */ function CatalogRows({ - parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level, now, + parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level, openChild, openChildAside, refresh, toggleBranch, closeCatalog, t, }: CatalogRowsProps & { t: TranslateNS }) { + const [now, setNow] = useState(() => Date.now()) + const running = catalog.entries.some(entry => entry.activity === 'running') + useEffect(() => { + if (!running) return + const timer = setInterval(() => { setNow(Date.now()) }, 1_000) + return () => { clearInterval(timer) } + }, [running]) const emptyLoading = catalog.state === 'loading' && catalog.entries.length === 0 - const reserveDisclosure = catalog.entries.some( - entry => entry.kind === 'child' && entry.hasChildren, - ) + const reserveDisclosure = catalog.entries.some(entry => !isKnownLeaf(catalogs[entry.id])) return ( <> {emptyLoading && ( - + )} {catalog.state === 'error' && (
@@ -272,35 +230,10 @@ function CatalogRows({
)} {catalog.entries.map((entry) => { - if (entry.kind === 'diagnostic') { - const reason = diagnosticReason(entry, t) - return ( -
-
- {reserveDisclosure && } - - - - - {entry.id} - {reason} - -
-
- ) - } - const childCatalog = catalogs[entry.id] const isCurrent = entry.id === currentSessionId const isExpanded = expanded.has(entry.id) - const knownLeaf = !entry.hasChildren + const knownLeaf = isKnownLeaf(childCatalog) const childLoading = childCatalog === undefined || (childCatalog.state === 'loading' && childCatalog.entries.length === 0) const summary = summaries[entry.id] @@ -336,7 +269,11 @@ function CatalogRows({ .join(' · ') const open = (): void => { - openChild({ parentSessionId, childSessionId: entry.id, mode: entry.mode }) + openChild({ + parentSessionId, + childSessionId: entry.id, + mode: entry.mode, + }) closeCatalog() } const openAside = (event: MouseEvent): void => { @@ -433,14 +370,7 @@ function CatalogRows({ aria-busy={childLoading || undefined} > {childCatalog === undefined - ? ( - - ) + ? : ( } @@ -515,66 +445,44 @@ function catalogMenuPosition(trigger: HTMLButtonElement): CSSProperties { /** One trigger-plus-tree dropdown over the catalog rooted at `rootSessionId`. */ function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant, separator = false, - useSessions, openChild, openChildAside, refresh, setCatalogOpen, t, + useSessions, useSessionStatus, openChild, openChildAside, refresh, t, }: CatalogDropdownProps) { const ancestorSwitcher = variant === 'switcher' && openTitle !== undefined - const catalogs = useSessions(state => state.subagentsByParent) + const projections = useSessions(state => state.projectionsBySession) const summaries = useSessions(state => state.byId) + const statuses = useSessionStatus(value => value) + const catalogs = useMemo(() => Object.fromEntries(Object.entries(projections).map(([id, snapshot]) => [id, { + state: snapshot.state === 'idle' + ? snapshot.values.subagentCatalog === undefined ? 'loading' : 'ready' + : snapshot.state, + error: snapshot.error, + entries: (snapshot.values.subagentCatalog ?? []).map(entry => ({ + ...entry, activity: (statuses.get(entry.id)?.running ?? summaries[entry.id]?.running) === true ? 'running' as const : 'inactive' as const, + })), + }])), [projections, summaries, statuses]) const catalog = catalogs[rootSessionId] const [open, setOpen] = useState(false) const [menuPosition, setMenuPosition] = useState() - const [now, setNow] = useState(() => Date.now()) const [expanded, setExpanded] = useState>(() => new Set()) const rootRef = useRef(null) const triggerRef = useRef(null) const menuRef = useRef(null) const hoverOpenTimer = useRef | undefined>(undefined) const hoverCloseTimer = useRef | undefined>(undefined) - const observedCatalogs = useRef(new Set()) - const setCatalogOpenRef = useRef(setCatalogOpen) - setCatalogOpenRef.current = setCatalogOpen const currentEntry = currentSessionId === undefined ? undefined - : catalog?.entries.find(entry => entry.kind === 'child' && entry.id === currentSessionId) - const switcherDisplayTitle = currentEntry?.kind === 'child' + : catalog?.entries.find(entry => entry.id === currentSessionId) + const switcherDisplayTitle = currentEntry !== undefined ? currentEntry.label ?? currentEntry.id : displayTitle - const healthy = catalog?.entries.filter(entry => entry.kind === 'child') ?? [] - const descendants = useMemo( - () => indexSubagentDescendants(summaries).get(rootSessionId) ?? NO_DESCENDANTS, - [rootSessionId, summaries], - ) - // The catalog can arrive before the session-list baseline; never undercount - // the already-visible direct rows during that short bootstrap window. - const descendantCount = Math.max(healthy.length, descendants.count) - const totalCountKey = descendantCount === 1 ? 'count.total.one' : 'count.total.other' - const runningCountKey = descendants.runningCount === 1 ? 'count.running.one' : 'count.running.other' - // Session summaries can announce membership before the descriptor-backed catalog catches up. - // Keep that entry point visible through disabled loading rows; only catalog rows are navigable. - const summaryBackedLoading = (descendants.count > 0 || variant === 'switcher') - && (catalog === undefined || (catalog.state === 'ready' && catalog.entries.length === 0)) - const presentedCatalog: SubagentCatalogSnapshot | undefined = summaryBackedLoading - ? { - entries: [], - parentAvailable: catalog?.parentAvailable ?? false, - state: 'loading', - error: null, - } - : catalog - - const observeCatalog = (parentSessionId: SessionId, next: boolean): void => { - if (next) observedCatalogs.current.add(parentSessionId) - else observedCatalogs.current.delete(parentSessionId) - setCatalogOpen(parentSessionId, next) - } - - const closeAllCatalogs = (): void => { - for (const parentSessionId of observedCatalogs.current) { - setCatalogOpen(parentSessionId, false) - } - observedCatalogs.current.clear() - setExpanded(new Set()) - } + const directChildren = catalog?.entries ?? [] + const directCount = directChildren.length + const runningCount = directChildren.filter(entry => entry.activity === 'running').length + const totalCountKey = directCount === 1 ? 'count.total.one' : 'count.total.other' + const runningCountKey = runningCount === 1 ? 'count.running.one' : 'count.running.other' + const presentedCatalog: SubagentCatalogSnapshot | undefined = catalog ?? (variant === 'switcher' + ? { entries: [], state: 'loading', error: null } + : undefined) const cancelHoverClose = (): void => { if (hoverCloseTimer.current === undefined) return @@ -597,13 +505,12 @@ function CatalogDropdown({ if (trigger === null) return setOpen(true) setMenuPosition(catalogMenuPosition(trigger)) - setNow(Date.now()) - observeCatalog(rootSessionId, true) + refresh(rootSessionId) } else { setOpen(false) setMenuPosition(undefined) - closeAllCatalogs() + setExpanded(new Set()) } if (restoreFocus) queueMicrotask(() => { triggerRef.current?.focus() }) } @@ -634,11 +541,10 @@ function CatalogDropdown({ closing.add(parentSessionId) const branch = catalogs[parentSessionId] for (const entry of branch?.entries ?? []) { - if (entry.kind === 'child') visit(entry.id) + visit(entry.id) } } visit(root) - for (const parentSessionId of closing) observeCatalog(parentSessionId, false) setExpanded(current => new Set([...current].filter(id => !closing.has(id)))) } @@ -648,7 +554,7 @@ function CatalogDropdown({ return } setExpanded(current => new Set(current).add(childSessionId)) - observeCatalog(childSessionId, true) + refresh(childSessionId) } useEffect(() => { @@ -682,37 +588,24 @@ function CatalogDropdown({ } }, [open]) - useEffect(() => { - if (!open || descendants.runningCount === 0) return - const timer = setInterval(() => { setNow(Date.now()) }, 1_000) - return () => { clearInterval(timer) } - }, [open, descendants.runningCount]) - useEffect(() => () => { cancelHoverOpen() cancelHoverClose() - for (const parentSessionId of observedCatalogs.current) { - setCatalogOpenRef.current(parentSessionId, false) - } - observedCatalogs.current.clear() }, []) - // Visibility needs evidence of children (entries, summary-known descendants, - // or a failed load worth retrying). A bare loading catalog is not evidence: - // an opened menu or another active catalog consumer can start a refresh whose - // loading snapshot would otherwise flash the action on childless sessions. + // Visibility needs catalog evidence of children or a failed load worth retrying. + // An empty loading catalog is not evidence of children. const visible = presentedCatalog !== undefined && (variant === 'switcher' || presentedCatalog.state === 'error' - || presentedCatalog.entries.length > 0 - || descendantCount > 0) + || presentedCatalog.entries.length > 0) useEffect(() => { if (visible) return cancelHoverOpen() cancelHoverClose() if (!open) return setOpen(false) - closeAllCatalogs() + setExpanded(new Set()) }, [visible, open]) if (!visible) return null @@ -764,8 +657,8 @@ function CatalogDropdown({ aria-label={variant === 'switcher' ? t('switcher.aria', { title: switcherDisplayTitle }) : t( - descendants.runningCount > 0 ? runningCountKey : totalCountKey, - { count: descendants.runningCount > 0 ? descendants.runningCount : descendantCount }, + runningCount > 0 ? runningCountKey : totalCountKey, + { count: runningCount > 0 ? runningCount : directCount }, )} onClick={openTitle === undefined ? undefined @@ -785,12 +678,12 @@ function CatalogDropdown({ ? {switcherDisplayTitle} : ( <> - {descendants.runningCount > 0 && ( + {runningCount > 0 && ( )} - {t(totalCountKey, { count: descendantCount })} + {t(totalCountKey, { count: directCount })} )} {variant === 'switcher' @@ -815,7 +708,6 @@ function CatalogDropdown({ summaries={summaries} expanded={expanded} level={1} - now={now} openChild={openChild} openChildAside={openChildAside} refresh={refresh} @@ -832,17 +724,21 @@ function CatalogDropdown({ /** * Render one breadcrumb title together with its subagent navigation. * @param props - Breadcrumb title, session standard props, and catalog actions. - * @returns An ordinary-title descendant count, or a title-and-chevron sibling switcher. + * @returns An ordinary-title direct-child count, or a title-and-chevron sibling switcher. */ export function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, - useSessions, openChild, openChildAside, refresh, setCatalogOpen, t, + useSessions, useSession, useSessionStatus, openChild, openChildAside, refresh, t, }: SubagentHeaderLineageProps) { + const address = useSession(session => session.subagent?.address) const parentId = useSessions((state) => { - const summary = state.byId[lineageSessionId] - return summary?.origin === 'subagent' ? summary.parentId : undefined + if (address?.childSessionId === lineageSessionId) return address.parentSessionId + for (const [parentId, snapshot] of Object.entries(state.projectionsBySession)) { + if (snapshot.values.subagentCatalog?.some(entry => entry.id === lineageSessionId)) return parentId as SessionId + } + return undefined }) - const shared = { useSessions, openChild, openChildAside, refresh, setCatalogOpen, t } + const shared = { useSessions, useSessionStatus, openChild, openChildAside, refresh, t } if (parentId === undefined) { return ( = { - 'diagnostic.corrupt': 'corrupted session record', - 'diagnostic.unsupported': 'unsupported subagent record version', - 'diagnostic.unavailable': 'session record temporarily unavailable', 'duration.seconds': '{seconds}s', 'duration.minutes': '{minutes}m {seconds}s', 'duration.hours': '{hours}h {minutes}m {seconds}s', @@ -67,7 +60,6 @@ export const en: Record = { 'tokens.million': '{value}M', 'tokens.total': '{value} tok', 'loading.label': 'Loading subagents…', - 'loading.aria': 'Loading subagents', 'load.error': 'Unable to load subagents', 'retry': 'Retry', 'mode.oneShot': 'one-shot', diff --git a/packages/client/ui-subagent/src/client/sidebar-chat/index.tsx b/packages/client/ui-subagent/src/client/sidebar-chat/index.tsx index 375dcadfd3..a4fe489714 100644 --- a/packages/client/ui-subagent/src/client/sidebar-chat/index.tsx +++ b/packages/client/ui-subagent/src/client/sidebar-chat/index.tsx @@ -106,7 +106,7 @@ function subagentChatResourceProvider(sessions: ISessions): ResourceProvider<'su const address = parseSubagentChatAddress(resourceAddress) if (address === undefined) throw new Error(`ui-subagent: invalid chat resource address "${resourceAddress}"`) if (isAbortRequested(signal)) return - await sessions.refreshSubagents(address.parentSessionId) + await sessions.refreshProjections(address.parentSessionId) if (isAbortRequested(signal)) return const reference = sessions.retain(address, { source: 'sidebarChat', signal }) try { diff --git a/packages/client/ui-subagent/src/client/subagent-lineage.ts b/packages/client/ui-subagent/src/client/subagent-lineage.ts deleted file mode 100644 index d96ab4ff8a..0000000000 --- a/packages/client/ui-subagent/src/client/subagent-lineage.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** UI Subagent-owned projection of descendant counts from Session summaries. */ - -import type { SessionId } from '@deepseek-ai/dsh-session/types' - -interface LineageEntry { - readonly id: SessionId - readonly parentId?: SessionId - readonly origin?: 'subagent' - readonly running: boolean -} - -/** Descendant counts for one possible parent Session. */ -export interface SubagentDescendantSummary { - readonly count: number - readonly runningCount: number -} - -/* jscpd:ignore-start -- UI Subagent and UI Workspace independently project their own views. */ -/** - * Index uninterrupted subagent descendants under each ancestor. - * @param summaries - Session summaries keyed by id. - * @returns descendant totals keyed by possible parent id. - */ -export function indexSubagentDescendants( - summaries: Readonly>, -): ReadonlyMap { - const indexed = new Map() - for (const descendant of Object.values(summaries)) { - if (descendant.origin !== 'subagent') continue - const seen = new Set() - let current: LineageEntry | undefined = descendant - while (current?.origin === 'subagent' && current.parentId !== undefined && !seen.has(current.id)) { - seen.add(current.id) - const aggregate = indexed.get(current.parentId) - if (aggregate === undefined) { - indexed.set(current.parentId, { count: 1, runningCount: descendant.running ? 1 : 0 }) - } else { - aggregate.count += 1 - if (descendant.running) aggregate.runningCount += 1 - } - current = summaries[current.parentId] - } - } - return indexed -} -/* jscpd:ignore-end */ diff --git a/packages/client/ui-subagent/tests/browser-plugin.client.spec.ts b/packages/client/ui-subagent/tests/browser-plugin.client.spec.ts index ddebed5871..49b2ac6016 100644 --- a/packages/client/ui-subagent/tests/browser-plugin.client.spec.ts +++ b/packages/client/ui-subagent/tests/browser-plugin.client.spec.ts @@ -23,6 +23,7 @@ function summary(partial: Partial & { id: SessionId }): SessionS return { displayTitle: partial.id, running: false, + retainedBy: {}, updatedAt: 0, ...partial, } as SessionSummary @@ -34,21 +35,26 @@ const sid = (id: string) => id as SessionId function sessionsWith(sessions: SessionSummary[]) { const byId: Record = {} for (const s of sessions) byId[s.id] = s - const snapshot = { ids: sessions.map(s => s.id), byId, current: undefined } as unknown as SessionListState + const snapshot: SessionListState = { ids: sessions.map(s => s.id), byId, phase: 'ready', projectionsBySession: {}, jobsBySession: {} } const actionCalls: { method: string; args: unknown[] }[] = [] + const address: SubagentAddress = { + parentSessionId: sid('parent'), + childSessionId: sid('c1'), + mode: 'continuable', + } return { list: { getSnapshot: () => snapshot, subscribe: () => () => {}, }, actionCalls, - refreshSubagents: (parentSessionId: SessionId) => { - actionCalls.push({ method: 'refreshSubagents', args: [parentSessionId] }) + subagentAddress: (childSessionId: SessionId) => childSessionId === address.childSessionId + ? address + : undefined, + refreshProjections: (parentSessionId: SessionId) => { + actionCalls.push({ method: 'refreshProjections', args: [parentSessionId] }) return Promise.resolve() }, - setSubagentCatalogOpen: (parentSessionId: SessionId, open: boolean) => { - actionCalls.push({ method: 'setSubagentCatalogOpen', args: [parentSessionId, open] }) - }, } } @@ -114,7 +120,6 @@ describe('apply', () => { actions.openChild(address) actions.openChildAside(address) actions.refresh(sid('parent')) - actions.setCatalogOpen(sid('parent'), true) expect(face.actionCalls).toEqual([ { method: 'openSession', args: [address] }, { @@ -124,8 +129,7 @@ describe('apply', () => { { kind: 'subagentchat', preferNewPane: true }, ], }, - { method: 'refreshSubagents', args: [sid('parent')] }, - { method: 'setSubagentCatalogOpen', args: [sid('parent'), true] }, + { method: 'refreshProjections', args: [sid('parent')] }, ]) const composerEntry = ctx.slots.entries('conversation.composer') diff --git a/packages/client/ui-subagent/tests/conversation-ui.client.spec.tsx b/packages/client/ui-subagent/tests/conversation-ui.client.spec.tsx index 6f107cf202..626026fe54 100644 --- a/packages/client/ui-subagent/tests/conversation-ui.client.spec.tsx +++ b/packages/client/ui-subagent/tests/conversation-ui.client.spec.tsx @@ -3,9 +3,11 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, fireEvent, render, screen, within } from '@testing-library/react' import { makeTranslate, RemoteError } from '@deepseek-ai/dsh-client-test-runtime' import type { - SessionListState, SessionSummary, SubagentCatalogSnapshot, + SessionListState, SessionSummary, SessionSnapshot, } from '@deepseek-ai/dsh-api-session-controller/client' +import type { SubagentAddress, SubagentCatalogRow } from '@deepseek-ai/dsh-subagent/client' import type { SessionId } from '@deepseek-ai/dsh-session/types' +import type { SessionStatusSnapshot } from '@deepseek-ai/dsh-client-ui-session/client' import { SubagentHeaderLineage, type SubagentHeaderLineageProps, } from '../src/client/SubagentHeaderLineage.tsx' @@ -23,18 +25,19 @@ const CHILD = 'child' as SessionId const GRANDCHILD = 'grandchild' as SessionId const t: SubagentHeaderLineageProps['t'] = makeTranslate(zh) -function catalog(over: Partial = {}): SubagentCatalogSnapshot { +type CatalogFixture = { entries: readonly SubagentCatalogRow[]; parentAvailable: boolean; state: 'loading' | 'ready' | 'error'; error: SessionListState['projectionsBySession'][SessionId]['error'] } + +function catalog(over: Partial = {}): CatalogFixture { return { entries: [ { - kind: 'child', id: CHILD, mode: 'continuable', label: 'worker', - activity: 'running', hasChildren: true, + id: CHILD, mode: 'continuable', label: 'worker', + activity: 'running', }, { - kind: 'child', id: 'child-2' as SessionId, mode: 'one-shot', - label: 'reviewer', activity: 'inactive', hasChildren: false, + id: 'child-2' as SessionId, mode: 'one-shot', + label: 'reviewer', activity: 'inactive', }, - { kind: 'diagnostic', id: 'bad' as SessionId, reason: 'corrupt' }, ], parentAvailable: true, state: 'ready', @@ -44,25 +47,34 @@ function catalog(over: Partial = {}): SubagentCatalogSn } function props( - value: SubagentCatalogSnapshot | undefined, - nested: Readonly> = {}, + value: CatalogFixture | undefined, + nested: Readonly> = {}, summaries?: Readonly>, + boundAddress?: SubagentAddress, ) { + const catalogs = value === undefined ? nested : { [PARENT]: value, ...nested } + const statuses: SessionStatusSnapshot = new Map() const state = { ids: [CHILD], byId: summaries ?? { + ...Object.fromEntries(Object.values(catalogs).flatMap(catalog => catalog.entries.map(entry => [entry.id, { + id: entry.id, displayTitle: entry.label ?? entry.id, running: entry.activity === 'running', blank: false, updatedAt: 1, retainedBy: {}, + }]))), [CHILD]: { id: CHILD, title: '正在扫描项目文件', displayTitle: 'worker', - running: true, + running: Object.values(catalogs).some(catalog => catalog.entries.some(entry => entry.id === CHILD && entry.activity === 'running')), retainedBy: {}, blank: false, updatedAt: Date.now(), }, }, phase: 'ready', - subagentsByParent: value === undefined ? nested : { [PARENT]: value, ...nested }, + projectionsBySession: Object.fromEntries(Object.entries(catalogs).map(([id, catalog]) => [id, { + state: catalog.state, error: catalog.error, + values: { subagentCatalog: catalog.entries.map(({ activity: _activity, ...entry }) => ({ ...entry, createdAt: 1 })) }, + }])) , jobsBySession: {}, } satisfies SessionListState function useSessions(select: (snapshot: SessionListState) => T): T { @@ -71,10 +83,13 @@ function props( return { sessionId: PARENT, useSessions, + useSessionStatus: (select: (snapshot: SessionStatusSnapshot) => T): T => select(statuses), + useSession: (select: (snapshot: SessionSnapshot) => T): T => select({ + subagent: boundAddress === undefined ? undefined : { address: boundAddress }, + } as SessionSnapshot), openChild: vi.fn(), openChildAside: vi.fn(), refresh: vi.fn(), - setCatalogOpen: vi.fn(), lineageSessionId: PARENT, displayTitle: 'Parent title', t, @@ -101,10 +116,45 @@ function hoverCatalog(trigger: HTMLElement): void { } describe('SubagentHeaderLineage', () => { - it('aggregates live descendant activity onto the closed trigger', () => { + it('shows current catalog-only child status before Host list discovery', () => { + const input = props(catalog({ entries: [{ id: CHILD, mode: 'continuable', label: 'worker', activity: 'inactive' }] })) + const initial = input.useSessions(state => state) + const statuses: SessionStatusSnapshot = new Map([[CHILD, { + running: true, completionUnread: false, pendingInteraction: undefined, + }]]) + render( select({ ...initial, ids: [] })} + useSessionStatus={select => select(statuses)} + />) + expect(screen.getByRole('button', { name: '1 个子代理,正在运行' })).toBeTruthy() + }) + + it('shows retained children while an idle projection awaits refresh', () => { + const injected = props(catalog()) + const initial = injected.useSessions(state => state) + let projections: SessionListState['projectionsBySession'] = { + [PARENT]: { state: 'idle', error: null, values: {} }, + } + const current: SubagentHeaderLineageProps = { + ...injected, + useSessions: select => select({ ...initial, projectionsBySession: projections }), + } + const view = render() + expect(screen.queryByRole('button')).toBeNull() + + projections = { + [PARENT]: { ...initial.projectionsBySession[PARENT]!, state: 'idle' }, + } + view.rerender() + hoverCatalog(screen.getByRole('button')) + expect(screen.getByRole('treeitem', { name: /worker/ })).toBeTruthy() + expect(screen.getByRole('treeitem', { name: /reviewer/ })).toBeTruthy() + }) + + it('combines projected membership with Session activity on the closed trigger', () => { const summaries: Record = { [CHILD]: { - ...summary(CHILD, Date.now()), + ...summary(CHILD, Date.now()), running: true, parentId: PARENT, origin: 'subagent', }, @@ -126,17 +176,20 @@ describe('SubagentHeaderLineage', () => { expect(trigger.querySelector('[data-state="ongoing"]')).not.toBeNull() view.rerender() - const inactiveTrigger = screen.getByRole('button', { name: '3 个子代理' }) + const inactiveTrigger = screen.getByRole('button', { name: '2 个子代理' }) expect(inactiveTrigger.querySelector('[data-state="ongoing"]')).toBeNull() }) - it('does not aggregate subagents reached through an ordinary fork', () => { + it('does not count Sessions outside projected membership', () => { const fork = 'fork' as SessionId const forkChild = 'fork-child' as SessionId - render( { [forkChild]: { ...summary(forkChild, 1), parentId: fork, origin: 'subagent', running: true }, })} />) - const trigger = screen.getByRole('button', { name: '2 个子代理' }) + const trigger = screen.getByRole('button', { name: '1 个子代理' }) expect(trigger.querySelector('[data-state="ongoing"]')).toBeNull() }) - it('renders healthy counts, stable rows, diagnostics, and catalog-addressed navigation', () => { + it('renders stable rows and catalog-addressed navigation', () => { const input = props(catalog()) render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) hoverCatalog(trigger) - expect(input.setCatalogOpen).toHaveBeenCalledWith(PARENT, true) - expect(screen.getAllByRole('treeitem')).toHaveLength(3) + expect(input.refresh).toHaveBeenCalledWith(PARENT) + expect(screen.getAllByRole('treeitem')).toHaveLength(2) expect(screen.getByText('正在扫描项目文件 · 可继续 · 正在运行')).toBeTruthy() expect(screen.getByText('一次性 · 当前未运行')).toBeTruthy() - const diagnostic = screen.getByRole('treeitem', { name: /会话记录损坏/ }) - expect(diagnostic.getAttribute('aria-disabled')).toBe('true') expect(screen.getByRole('button', { name: '展开 worker 的下级子代理' })).toBeTruthy() - expect(screen.queryByRole('button', { name: '展开 reviewer 的下级子代理' })).toBeNull() - expect(screen.getByRole('treeitem', { name: /reviewer/ }).children).toHaveLength(2) + expect(screen.getByRole('button', { name: '展开 reviewer 的下级子代理' })).toBeTruthy() const sidebarButton = screen.getByRole('button', { name: '在侧边栏打开 worker' }) fireEvent.keyDown(sidebarButton, { key: 'Enter' }) @@ -175,16 +225,16 @@ describe('SubagentHeaderLineage', () => { hoverCatalog(trigger) fireEvent.click(screen.getByRole('treeitem', { name: /worker/ })) expect(input.openChild).toHaveBeenCalledWith({ - parentSessionId: PARENT, childSessionId: CHILD, mode: 'continuable', + parentSessionId: PARENT, + childSessionId: CHILD, mode: 'continuable', }) - expect(input.setCatalogOpen).toHaveBeenLastCalledWith(PARENT, false) }) - it('selects singular count keys for one descendant', () => { + it('selects singular count keys for one direct child', () => { const base = props(catalog({ entries: [{ - kind: 'child', id: CHILD, mode: 'continuable', label: 'worker', - activity: 'running', hasChildren: false, + id: CHILD, mode: 'continuable', label: 'worker', + activity: 'running', }], }), {}, { [CHILD]: { @@ -199,22 +249,26 @@ describe('SubagentHeaderLineage', () => { }) it('removes the disclosure column from branchless catalog levels', () => { - const input = props(catalog({ - entries: [{ - kind: 'child', id: CHILD, mode: 'continuable', label: 'worker', - activity: 'running', hasChildren: false, - }], - })) - render() + render() hoverCatalog(screen.getByRole('button', { name: /1 个子代理/ })) expect(screen.getByRole('treeitem', { name: /worker/ }).children).toHaveLength(1) }) + it('aligns a known leaf with siblings whose child catalog is still unknown', () => { + render() + hoverCatalog(screen.getByRole('button', { name: /1 个子代理,正在运行/ })) + + expect(screen.getByRole('treeitem', { name: /worker/ }).children).toHaveLength(2) + expect(screen.getByRole('button', { name: /展开 reviewer/ })).toBeTruthy() + }) + it('supports trigger/menu keyboard traversal, Escape focus restore, and outside close', async () => { const input = props(catalog()) render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) fireEvent.keyDown(trigger, { key: 'ArrowDown' }) await Promise.resolve() expect(document.activeElement).toBe(screen.getByRole('treeitem', { name: /worker/ })) @@ -243,7 +297,7 @@ describe('SubagentHeaderLineage', () => { await act(async () => { await vi.advanceTimersByTimeAsync(duration) }) } const view = render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) const triggerRect = vi.spyOn(trigger, 'getBoundingClientRect') .mockReturnValue({ bottom: 40, left: 50 } as DOMRect) @@ -280,7 +334,7 @@ describe('SubagentHeaderLineage', () => { it('repositions an open catalog after viewport resize and document scroll', () => { const view = render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) const bounds = vi.spyOn(trigger, 'getBoundingClientRect') bounds.mockReturnValue({ bottom: 20, left: 30 } as DOMRect) hoverCatalog(trigger) @@ -303,7 +357,7 @@ describe('SubagentHeaderLineage', () => { it('cancels a pending hover when the trigger becomes hidden', async () => { vi.useFakeTimers() const view = render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) fireEvent.mouseEnter(trigger.parentElement!) await vi.advanceTimersByTimeAsync(149) @@ -315,40 +369,36 @@ describe('SubagentHeaderLineage', () => { expect(screen.queryByRole('tree')).toBeNull() }) - it('covers diagnostic variants, fallback labels, and keyboard row activation', () => { - const unsupported = 'unsupported' as SessionId - const unavailable = 'unavailable' as SessionId + it('covers fallback labels and keyboard row activation', () => { const unlabeled = 'unlabeled' as SessionId const input = props(catalog({ entries: [ - { kind: 'diagnostic', id: unsupported, reason: 'unsupported' }, - { kind: 'diagnostic', id: unavailable, reason: 'unavailable' }, { - kind: 'child', id: CHILD, mode: 'continuable', label: 'worker', - activity: 'running', hasChildren: false, + id: CHILD, mode: 'continuable', label: 'worker', + activity: 'running', }, { - kind: 'child', id: unlabeled, mode: 'one-shot', - activity: 'inactive', hasChildren: false, + id: unlabeled, mode: 'one-shot', + activity: 'inactive', }, ], })) render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) fireEvent.keyDown(trigger, { key: 'Tab' }) expect(screen.queryByRole('tree')).toBeNull() hoverCatalog(trigger) - expect(screen.getByRole('treeitem', { name: /子代理记录版本不受支持/ })).toBeTruthy() - expect(screen.getByRole('treeitem', { name: /会话记录暂不可用/ })).toBeTruthy() fireEvent.keyDown(screen.getByRole('treeitem', { name: /worker/ }), { key: 'Enter' }) expect(input.openChild).toHaveBeenLastCalledWith({ - parentSessionId: PARENT, childSessionId: CHILD, mode: 'continuable', + parentSessionId: PARENT, + childSessionId: CHILD, mode: 'continuable', }) hoverCatalog(trigger) fireEvent.keyDown(screen.getByRole('treeitem', { name: /unlabeled/ }), { key: ' ' }) expect(input.openChild).toHaveBeenLastCalledWith({ - parentSessionId: PARENT, childSessionId: unlabeled, mode: 'one-shot', + parentSessionId: PARENT, + childSessionId: unlabeled, mode: 'one-shot', }) }) @@ -391,12 +441,10 @@ describe('SubagentHeaderLineage', () => { }, } as const const entries = rows.map(([id, activity]) => ({ - kind: 'child' as const, id: id as SessionId, mode: 'continuable' as const, label: id, activity, - hasChildren: false, })) const summaries = Object.fromEntries(rows.map(([ id, activity, settledMs, activeSince, activeThrough, updatedAt, @@ -459,12 +507,47 @@ describe('SubagentHeaderLineage', () => { expect(screen.getByRole('treeitem', { name: /interrupted.*当前未运行.*123M tok · 6秒/ })).toBeTruthy() }) + it('ticks expanded running grandchildren under an idle child and releases their clock on collapse', async () => { + const now = 2_000_000_000_000 + vi.useFakeTimers() + vi.setSystemTime(now) + const input = props(catalog({ entries: [{ + id: CHILD, mode: 'continuable', label: 'worker', activity: 'inactive', + }] }), { + [CHILD]: catalog({ entries: [{ + id: GRANDCHILD, mode: 'continuable', label: 'indexer', activity: 'running', + }] }), + }, { + [GRANDCHILD]: { + ...summary(GRANDCHILD, now), + parentId: CHILD, + origin: 'subagent', + running: true, + projectionValues: { + subagentTiming: { settledMs: 0, active: { since: now - 5_000, through: now } }, + }, + }, + }) + render() + hoverCatalog(screen.getByRole('button', { name: '1 个子代理' })) + const beforeExpand = vi.getTimerCount() + fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' })) + expect(screen.getByRole('treeitem', { name: /indexer.*5秒/ })).toBeTruthy() + await act(async () => { await vi.advanceTimersByTimeAsync(1_000) }) + expect(screen.getByRole('treeitem', { name: /indexer.*6秒/ })).toBeTruthy() + fireEvent.click(screen.getByRole('button', { name: '收起 worker 的下级子代理' })) + expect(vi.getTimerCount()).toBe(beforeExpand) + await act(async () => { await vi.advanceTimersByTimeAsync(1_000) }) + fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' })) + expect(screen.getByRole('treeitem', { name: /indexer.*7秒/ })).toBeTruthy() + }) + it('lazily expands and collapses descendant catalogs with direct-parent navigation', () => { const childCatalog = catalog({ entries: [ { - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'inactive', hasChildren: false, + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'inactive', }, ], }) @@ -474,24 +557,24 @@ describe('SubagentHeaderLineage', () => { [GRANDCHILD]: grandchildCatalog, }) render() - hoverCatalog(screen.getByRole('button', { name: /2 个子代理/ })) + hoverCatalog(screen.getByRole('button', { name: /1 个子代理,正在运行/ })) fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' })) - expect(input.setCatalogOpen).toHaveBeenCalledWith(CHILD, true) + expect(input.refresh).toHaveBeenCalledWith(CHILD) const nested = screen.getByRole('treeitem', { name: /indexer/ }) expect(nested.getAttribute('aria-level')).toBe('2') fireEvent.click(nested) expect(input.openChild).toHaveBeenCalledWith({ - parentSessionId: CHILD, childSessionId: GRANDCHILD, mode: 'continuable', + parentSessionId: CHILD, + childSessionId: GRANDCHILD, mode: 'continuable', }) - expect(input.setCatalogOpen).toHaveBeenCalledWith(PARENT, false) - expect(input.setCatalogOpen).toHaveBeenCalledWith(CHILD, false) }) - it('shows known descendant rows while their catalog loads', () => { + it('shows one generic state while a child catalog loads', () => { const secondGrandchild = 'grandchild-2' as SessionId const summaries = { + [CHILD]: { ...summary(CHILD, 1), running: true }, [GRANDCHILD]: { ...summary(GRANDCHILD, 1), parentId: CHILD, origin: 'subagent' as const, }, @@ -502,32 +585,30 @@ describe('SubagentHeaderLineage', () => { } const deferred = props(catalog(), {}, summaries) const view = render() - hoverCatalog(screen.getByRole('button', { name: /2 个子代理/ })) + hoverCatalog(screen.getByRole('button', { name: /1 个子代理,正在运行/ })) fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' })) - expect(deferred.setCatalogOpen).toHaveBeenCalledWith(CHILD, true) + expect(deferred.refresh).toHaveBeenCalledWith(CHILD) expect(screen.getByRole('group').getAttribute('aria-busy')).toBe('true') - const loadingRows = screen.getAllByRole('treeitem', { name: '正在加载子代理' }) - expect(loadingRows).toHaveLength(2) - expect(loadingRows.every(row => row.getAttribute('aria-level') === '2')).toBe(true) - expect(loadingRows[1]?.querySelector('[data-state="ongoing"]')).not.toBeNull() + expect(screen.getByText('正在加载子代理…')).toBeTruthy() + expect(screen.queryByRole('treeitem', { name: '正在加载子代理' })).toBeNull() const loading = props(catalog(), { [CHILD]: catalog({ entries: [], state: 'loading' }), }, summaries) view.rerender() - expect(screen.getAllByRole('treeitem', { name: '正在加载子代理' })).toHaveLength(2) + expect(screen.getByText('正在加载子代理…')).toBeTruthy() const ready = props(catalog(), { [CHILD]: catalog({ entries: [ { - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'inactive', hasChildren: false, + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'inactive', }, { - kind: 'child', id: secondGrandchild, mode: 'one-shot', - label: 'critic', activity: 'running', hasChildren: false, + id: secondGrandchild, mode: 'one-shot', + label: 'critic', activity: 'running', }, ], }), @@ -536,20 +617,20 @@ describe('SubagentHeaderLineage', () => { expect(screen.getByRole('group').getAttribute('aria-busy')).toBeNull() expect(screen.getByRole('treeitem', { name: /indexer/ }).querySelector('[data-state="idle"]')).not.toBeNull() expect(screen.getByRole('treeitem', { name: /critic/ }).querySelector('[data-state="ongoing"]')).not.toBeNull() - expect(screen.queryByRole('treeitem', { name: '正在加载子代理' })).toBeNull() + expect(screen.queryByText('正在加载子代理…')).toBeNull() }) it('uses ArrowRight and ArrowLeft for branch disclosure', async () => { const input = props(catalog(), { [CHILD]: catalog({ entries: [{ - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'running', hasChildren: false, + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'running', }], }), }) render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) fireEvent.keyDown(trigger, { key: 'ArrowDown' }) await Promise.resolve() const worker = screen.getByRole('treeitem', { name: /worker/ }) @@ -557,29 +638,23 @@ describe('SubagentHeaderLineage', () => { expect(screen.getByRole('treeitem', { name: /indexer/ })).toBeTruthy() fireEvent.keyDown(worker, { key: 'ArrowLeft' }) expect(screen.queryByRole('treeitem', { name: /indexer/ })).toBeNull() - expect(input.setCatalogOpen).toHaveBeenCalledWith(CHILD, false) }) it('closes expanded descendants even when their own catalogs have not arrived', () => { const input = props(catalog(), { [CHILD]: catalog({ - entries: [ - { - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'running', hasChildren: true, - }, - { kind: 'diagnostic', id: 'nested-bad' as SessionId, reason: 'corrupt' }, - ], + entries: [{ + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'running', + }], }), }) render() - hoverCatalog(screen.getByRole('button', { name: /2 个子代理/ })) + hoverCatalog(screen.getByRole('button', { name: /1 个子代理,正在运行/ })) fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' })) fireEvent.click(screen.getByRole('button', { name: '展开 indexer 的下级子代理' })) fireEvent.click(screen.getByRole('button', { name: '收起 worker 的下级子代理' })) - expect(input.setCatalogOpen).toHaveBeenCalledWith(GRANDCHILD, false) - expect(input.setCatalogOpen).toHaveBeenCalledWith(CHILD, false) expect(screen.queryByRole('treeitem', { name: /indexer/ })).toBeNull() }) @@ -605,7 +680,7 @@ describe('SubagentHeaderLineage', () => { expect(failed.refresh).toHaveBeenCalledWith(PARENT) }) - it('keeps known descendants reachable while their catalog is absent or stale-empty', () => { + it('does not expose summary-only descendants as catalog rows', () => { const second = 'child-2' as SessionId const summaries = { [CHILD]: { @@ -617,19 +692,11 @@ describe('SubagentHeaderLineage', () => { } const absent = props(undefined, {}, summaries) const view = render() - - const trigger = screen.getByRole('button', { name: '1 个子代理,正在运行' }) - expect(within(trigger).getByText('2 个子代理')).toBeTruthy() - hoverCatalog(trigger) - expect(absent.setCatalogOpen).toHaveBeenCalledWith(PARENT, true) - expect(screen.getAllByRole('treeitem', { name: '正在加载子代理' })).toHaveLength(2) - expect(absent.openChild).not.toHaveBeenCalled() + expect(screen.queryByRole('button')).toBeNull() const staleEmpty = props(catalog({ entries: [] }), {}, summaries) view.rerender() - expect(screen.getByRole('button', { name: '1 个子代理,正在运行' })).toBeTruthy() - expect(screen.getAllByRole('treeitem', { name: '正在加载子代理' })).toHaveLength(2) - expect(staleEmpty.openChild).not.toHaveBeenCalled() + expect(screen.queryByRole('button')).toBeNull() }) it('hides a bare loading catalog and keeps the error fallback without focusable rows', async () => { @@ -654,7 +721,7 @@ describe('SubagentHeaderLineage', () => { it('navigates from outside the tree and tolerates a deferred focus after unmount', async () => { const input = props(catalog()) const view = render() - const trigger = screen.getByRole('button', { name: /2 个子代理/ }) + const trigger = screen.getByRole('button', { name: /1 个子代理,正在运行/ }) hoverCatalog(trigger) fireEvent.keyDown(screen.getByRole('tree'), { key: 'ArrowUp' }) expect(document.activeElement).toBe(screen.getByRole('treeitem', { name: /reviewer/ })) @@ -667,27 +734,25 @@ describe('SubagentHeaderLineage', () => { const populated = props(catalog(), { [CHILD]: catalog({ entries: [{ - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'inactive', hasChildren: false, + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'inactive', }], }), }) const view = render() - hoverCatalog(screen.getByRole('button', { name: /2 个子代理/ })) + hoverCatalog(screen.getByRole('button', { name: /1 个子代理,正在运行/ })) fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' })) const empty = props(catalog({ entries: [] })) view.rerender() expect(screen.queryByRole('button')).toBeNull() - expect(empty.setCatalogOpen).toHaveBeenCalledWith(PARENT, false) - expect(empty.setCatalogOpen).toHaveBeenCalledWith(CHILD, false) }) - it('places a separator before a visible ordinary-session descendant count', () => { + it('places a separator before a visible ordinary-session direct-child count', () => { const view = render() expect(screen.getByText('/')).toBeTruthy() - expect(screen.getByRole('button', { name: /2 个子代理/ })).toBeTruthy() + expect(screen.getByRole('button', { name: /1 个子代理,正在运行/ })).toBeTruthy() view.rerender() expect(screen.queryByText('/')).toBeNull() @@ -720,21 +785,37 @@ describe('SubagentHeaderLineage', () => { expect(switcherIcon?.getAttribute('height')).toBe('16') hoverCatalog(switcher) - expect(input.setCatalogOpen).toHaveBeenCalledWith(PARENT, true) + expect(input.refresh).toHaveBeenCalledWith(PARENT) const current = screen.getByRole('treeitem', { name: /worker/ }) expect(current.getAttribute('aria-current')).toBe('true') expect(within(current).getByText('worker').className).toContain('currentLabel') fireEvent.click(screen.getByRole('treeitem', { name: /reviewer/ })) expect(input.openChild).toHaveBeenCalledWith({ - parentSessionId: PARENT, childSessionId: sibling, mode: 'one-shot', + parentSessionId: PARENT, + childSessionId: sibling, mode: 'one-shot', }) }) + it('does not derive a subagent address from Session summary lineage', () => { + const input = { + ...props(undefined, {}, { + [CHILD]: { + ...summary(CHILD, 1), parentId: PARENT, origin: 'subagent' as const, + }, + }), + lineageSessionId: CHILD, + displayTitle: 'worker', + } + render() + + expect(screen.queryByRole('button', { name: '切换子代理:worker' })).toBeNull() + }) + it('falls back to the catalog session id when the selected row has no label', () => { const input = { ...props(catalog({ entries: [{ - kind: 'child', id: CHILD, mode: 'one-shot', - activity: 'inactive', hasChildren: false, + id: CHILD, mode: 'one-shot', + activity: 'inactive', }] }), {}, { [CHILD]: { ...summary(CHILD, 1), parentId: PARENT, origin: 'subagent' as const, @@ -753,8 +834,8 @@ describe('SubagentHeaderLineage', () => { const input = { ...props(catalog(), { [CHILD]: catalog({ entries: [{ - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'inactive', hasChildren: false, + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'inactive', }] }), }, { [CHILD]: { @@ -797,13 +878,14 @@ describe('SubagentHeaderLineage', () => { ...summary(CHILD, 1), parentId: PARENT, origin: 'subagent' as const, displayTitle: '正在扫描项目文件', }, - }), + }, { parentSessionId: PARENT, childSessionId: CHILD, mode: 'continuable' }), lineageSessionId: CHILD, displayTitle: '正在扫描项目文件', ...(openTitle === undefined ? {} : { openTitle }), } render() + expect(screen.getByRole('button', { name: '切换子代理:正在扫描项目文件' })).toBeTruthy() expect(input.refresh).not.toHaveBeenCalled() }) @@ -811,8 +893,8 @@ describe('SubagentHeaderLineage', () => { const input = { ...props(catalog(), { [CHILD]: catalog({ entries: [{ - kind: 'child', id: GRANDCHILD, mode: 'continuable', - label: 'indexer', activity: 'inactive', hasChildren: false, + id: GRANDCHILD, mode: 'continuable', + label: 'indexer', activity: 'inactive', }] }), }, { [CHILD]: { @@ -830,7 +912,7 @@ describe('SubagentHeaderLineage', () => { hoverCatalog(screen.getByRole('button', { name: '切换子代理:indexer' })) - expect(input.setCatalogOpen).toHaveBeenCalledWith(CHILD, true) + expect(input.refresh).toHaveBeenCalledWith(CHILD) const current = screen.getByRole('treeitem', { name: /indexer/ }) expect(current.getAttribute('aria-current')).toBe('true') expect(within(current).getByText('indexer').className).toContain('currentLabel') diff --git a/packages/client/ui-subagent/tests/sidebar-chat.client.spec.tsx b/packages/client/ui-subagent/tests/sidebar-chat.client.spec.tsx index a75f111f5f..143a0cb595 100644 --- a/packages/client/ui-subagent/tests/sidebar-chat.client.spec.tsx +++ b/packages/client/ui-subagent/tests/sidebar-chat.client.spec.tsx @@ -64,7 +64,7 @@ describe('Sidebar chat registration', () => { [Symbol.dispose]: release, } as unknown as SessionReference const retain = vi.fn(() => reference) - const refreshSubagents = vi.fn(() => Promise.resolve()) + const refreshProjections = vi.fn(() => Promise.resolve()) const list = { getSnapshot: () => ({ ids: [], @@ -75,7 +75,7 @@ describe('Sidebar chat registration', () => { }, }, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, } as unknown as SessionListState), subscribe: () => () => {}, @@ -84,7 +84,7 @@ describe('Sidebar chat registration', () => { let definition: SidebarRightTabDefinition | undefined const registrations: { options: Record; component: unknown }[] = [] const ctx = { - sessions: { retain, refreshSubagents, list } as unknown as ISessions, + sessions: { retain, refreshProjections, list } as unknown as ISessions, resources: { register: (value: ResourceProvider<'subagentchat'>) => { provider = value; return () => {} } }, sidebarRightTabs: { register: (value: SidebarRightTabDefinition) => { definition = value; return () => {} } }, slots: { @@ -114,7 +114,7 @@ describe('Sidebar chat registration', () => { const controller = new AbortController() const stream = provider!.open(subagentChatAddress(ADDRESS), { signal: controller.signal })[Symbol.asyncIterator]() expect(await stream.next()).toEqual({ done: false, value: { ok: true, value: { address: ADDRESS, reference } } }) - expect(refreshSubagents).toHaveBeenCalledWith(PARENT) + expect(refreshProjections).toHaveBeenCalledWith(PARENT) expect(retain).toHaveBeenCalledWith(ADDRESS, { source: 'sidebarChat', signal: controller.signal }) const completion = stream.next() await Promise.resolve() @@ -130,7 +130,7 @@ describe('Sidebar chat registration', () => { expect(release).toHaveBeenCalledTimes(2) let finishRefresh: (() => void) | undefined - refreshSubagents.mockImplementationOnce(() => new Promise((resolve) => { finishRefresh = resolve })) + refreshProjections.mockImplementationOnce(() => new Promise((resolve) => { finishRefresh = resolve })) const abortedDuringRefresh = new AbortController() const pending = provider!.open( subagentChatAddress(ADDRESS), { signal: abortedDuringRefresh.signal }, @@ -218,7 +218,7 @@ describe('Sidebar chat components', () => { useSession: (select: (value: SessionSnapshot) => unknown) => select(snapshot), useConversation: (select: (value: { activeTargets: ReadonlySet }) => unknown) => select({ activeTargets: new Set() }), useSessions: (select: (value: SessionListState) => unknown) => select({ - ids: [], byId: { [CHILD]: { blank: summaryBlank } }, phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + ids: [], byId: { [CHILD]: { blank: summaryBlank } }, phase: 'ready', projectionsBySession: {}, jobsBySession: {}, } as unknown as SessionListState), renderFactorySlot, } as unknown as Parameters[0])} />) diff --git a/packages/client/ui-subagent/tests/subagent-lineage.client.spec.ts b/packages/client/ui-subagent/tests/subagent-lineage.client.spec.ts deleted file mode 100644 index 17b3a8acdf..0000000000 --- a/packages/client/ui-subagent/tests/subagent-lineage.client.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { SessionId } from '@deepseek-ai/dsh-session/types' -import { indexSubagentDescendants } from '../src/client/subagent-lineage.ts' - -const sid = (id: string): SessionId => id as SessionId - -describe('UI Subagent descendant projection', () => { - it('counts nested running descendants and stops at ordinary forks', () => { - const owner = { id: sid('owner'), running: false } - const child = { id: sid('child'), parentId: owner.id, origin: 'subagent' as const, running: false } - const grandchild = { id: sid('grandchild'), parentId: child.id, origin: 'subagent' as const, running: true } - const fork = { id: sid('fork'), parentId: child.id, running: false } - const forkChild = { id: sid('fork-child'), parentId: fork.id, origin: 'subagent' as const, running: true } - const result = indexSubagentDescendants(Object.fromEntries( - [owner, child, grandchild, fork, forkChild].map(item => [item.id, item]), - )) - expect(result.get(owner.id)).toEqual({ count: 2, runningCount: 1 }) - expect(result.get(child.id)).toEqual({ count: 1, runningCount: 1 }) - expect(result.get(fork.id)).toEqual({ count: 1, runningCount: 1 }) - }) - - it('terminates cycles and retains missing-parent aggregates', () => { - const cycleA = { id: sid('a'), parentId: sid('b'), origin: 'subagent' as const, running: false } - const cycleB = { id: sid('b'), parentId: sid('a'), origin: 'subagent' as const, running: false } - const orphan = { id: sid('orphan'), parentId: sid('missing'), origin: 'subagent' as const, running: true } - const result = indexSubagentDescendants({ [cycleA.id]: cycleA, [cycleB.id]: cycleB, [orphan.id]: orphan }) - expect(result.get(cycleA.id)?.count).toBe(2) - expect(result.get(cycleB.id)?.count).toBe(2) - expect(result.get(sid('missing'))).toEqual({ count: 1, runningCount: 1 }) - }) -}) diff --git a/packages/client/ui-theme/tests/appearance-row.client.spec.tsx b/packages/client/ui-theme/tests/appearance-row.client.spec.tsx index 35ee863fd4..6f36e9fe6a 100644 --- a/packages/client/ui-theme/tests/appearance-row.client.spec.tsx +++ b/packages/client/ui-theme/tests/appearance-row.client.spec.tsx @@ -26,7 +26,7 @@ const COPY: Record = { function emptySessions() { const store = createSnapshotStore( - { ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {} }) + { ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {} }) return bindSnapshotSelector(store) } function emptyWorkspaces() { diff --git a/packages/client/ui-theme/tests/font-size-row.client.spec.tsx b/packages/client/ui-theme/tests/font-size-row.client.spec.tsx index 23a049ce13..ded9cc0377 100644 --- a/packages/client/ui-theme/tests/font-size-row.client.spec.tsx +++ b/packages/client/ui-theme/tests/font-size-row.client.spec.tsx @@ -28,7 +28,7 @@ const COPY: Record = { /** Empty global standard-kit hooks (the row reads neither). */ function emptySessions() { const store = createSnapshotStore( - { ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {} }) + { ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {} }) return bindSnapshotSelector(store) } function emptyWorkspaces() { diff --git a/packages/client/ui-tool/tests/coverage-tails.client.spec.tsx b/packages/client/ui-tool/tests/coverage-tails.client.spec.tsx index 2c0fe097a2..80615b752f 100644 --- a/packages/client/ui-tool/tests/coverage-tails.client.spec.tsx +++ b/packages/client/ui-tool/tests/coverage-tails.client.spec.tsx @@ -28,7 +28,7 @@ function listStore() { [SID]: { id: SID, title: 'r', displayTitle: 'r', running: false, retainedBy: {}, blank: false, updatedAt: 0 }, }, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, }) } diff --git a/packages/client/ui-tool/tests/diff-card.client.spec.tsx b/packages/client/ui-tool/tests/diff-card.client.spec.tsx index 2c50e9f6bb..d1b298c8fd 100644 --- a/packages/client/ui-tool/tests/diff-card.client.spec.tsx +++ b/packages/client/ui-tool/tests/diff-card.client.spec.tsx @@ -202,7 +202,7 @@ describe('FileMutationRow diff card', () => { ids: [SID], byId: { [SID]: { id: SID, displayTitle: 'r', running: false, retainedBy: {}, blank: false, updatedAt: 0, cwd: '/w/app' } }, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, }) const rowProps = (block: RunningToolCall | ToolResultNode, toolName = 'edit'): FileMutationRowProps => ({ diff --git a/packages/client/ui-tool/tests/image-card.client.spec.tsx b/packages/client/ui-tool/tests/image-card.client.spec.tsx index 53578e25d9..74b2a9a127 100644 --- a/packages/client/ui-tool/tests/image-card.client.spec.tsx +++ b/packages/client/ui-tool/tests/image-card.client.spec.tsx @@ -269,7 +269,7 @@ describe('ReadImageRow keyed toolview', () => { byId: { [SID]: { id: SID, displayTitle: 'r', running: false, blank: false, updatedAt: 0, cwd: '/w/app' } }, current: SID, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, currentAddress: undefined, } as unknown as SessionListState) diff --git a/packages/client/ui-tool/tests/read-card.client.spec.tsx b/packages/client/ui-tool/tests/read-card.client.spec.tsx index a268273e8e..366c4c69cb 100644 --- a/packages/client/ui-tool/tests/read-card.client.spec.tsx +++ b/packages/client/ui-tool/tests/read-card.client.spec.tsx @@ -206,7 +206,7 @@ describe('ReadRow keyed toolview', () => { ids: [SID], byId: { [SID]: { id: SID, displayTitle: 'r', running: false, retainedBy: {}, blank: false, updatedAt: 0, cwd: '/w/app' } }, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, }) const rowProps = (block: RunningToolCall | ToolResultNode): Parameters[0] => ({ diff --git a/packages/client/ui-tool/tests/terminal-card.client.spec.tsx b/packages/client/ui-tool/tests/terminal-card.client.spec.tsx index cb95b6fcf6..bdeb4ee60e 100644 --- a/packages/client/ui-tool/tests/terminal-card.client.spec.tsx +++ b/packages/client/ui-tool/tests/terminal-card.client.spec.tsx @@ -407,7 +407,7 @@ describe('BashRow terminal card', () => { ids: [SID], byId: { [SID]: { id: SID, displayTitle: 'r', running: false, retainedBy: {}, blank: false, updatedAt: 0 } }, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, }) const rowProps = (block: RunningToolCall | ToolResultNode): BashRowProps => ({ diff --git a/packages/client/ui-tool/tests/tool-fixtures.client.ts b/packages/client/ui-tool/tests/tool-fixtures.client.ts index dfb73e25a5..0ec1ad4397 100644 --- a/packages/client/ui-tool/tests/tool-fixtures.client.ts +++ b/packages/client/ui-tool/tests/tool-fixtures.client.ts @@ -106,14 +106,11 @@ export function toolSessionEvents(nodes: readonly ToolResultNode[]): readonly Se step: 1, message: { id: `result-${node.callId}`, - role: 'user', + role: 'tool', source: { kind: 'tool', callId: node.callId }, - content: [{ - type: 'tool-result', - toolCallId: node.callId, - content: node.content.map(block => ({ ...block })), - isError: node.isError, - }], + toolCallId: node.callId, + content: node.content.map(block => ({ ...block })), + isError: node.isError, }, ...(node.error === undefined ? {} : { error: node.error }), ...(node.meta === undefined ? {} : { meta: node.meta }), diff --git a/packages/client/ui-trajectory/README.i18n.yaml b/packages/client/ui-trajectory/README.i18n.yaml index e865300cf5..94e9837fe7 100644 --- a/packages/client/ui-trajectory/README.i18n.yaml +++ b/packages/client/ui-trajectory/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-trajectory/README.md -README.md: 35135c726d59669ee6368d33ba35882897df7b15 -README.zh.md: ddde852f56924599b46a7f813619dcfc7d099714 +README.md: d15b1c7c6d605ba1b73180566a84fe29ab08530c +README.zh.md: 87cbae17c53a112cc62054a6150df9565a7bd8c0 diff --git a/packages/client/ui-trajectory/README.md b/packages/client/ui-trajectory/README.md index 35135c726d..d15b1c7c6d 100644 --- a/packages/client/ui-trajectory/README.md +++ b/packages/client/ui-trajectory/README.md @@ -94,6 +94,8 @@ None; this package neither assembles nor sends a provider request. +- **Developer messages are not displayed** — presentation is intentionally deferred; encountering `developer/message` throws instead of rendering a fallback row. + These limits define what the view can show while work is in flight; they are current package constraints. diff --git a/packages/client/ui-trajectory/README.zh.md b/packages/client/ui-trajectory/README.zh.md index ddde852f56..87cbae17c5 100644 --- a/packages/client/ui-trajectory/README.zh.md +++ b/packages/client/ui-trajectory/README.zh.md @@ -94,6 +94,8 @@ Trajectory 要求会话壳把 composer 作为浮层置于全高记录表上方 +- **不展示 developer 消息** — 展示能力有意留待后续实现;遇到 `developer/message` 时抛出错误,不渲染回退行。 + 这些限制定义工作仍在进行时视图能显示什么;它们是当前包约束。 diff --git a/packages/client/ui-trajectory/src/client/TrajectoryTable.tsx b/packages/client/ui-trajectory/src/client/TrajectoryTable.tsx index fb765dca97..30bd1f98c6 100644 --- a/packages/client/ui-trajectory/src/client/TrajectoryTable.tsx +++ b/packages/client/ui-trajectory/src/client/TrajectoryTable.tsx @@ -887,12 +887,6 @@ function messageSourceLabel(source: unknown, t: TrajectoryTranslate): string { const properties = source as Record const kind = properties.kind if (kind === 'user') return t('source.user') - if (kind === 'plugin') { - const plugin = properties.plugin - return typeof plugin === 'string' && plugin !== '' - ? t('source.pluginNamed', { plugin }) - : t('source.plugin') - } if (kind === 'goal') { const round = properties.round return typeof round === 'number' && round > 0 diff --git a/packages/client/ui-trajectory/src/client/trajectory-compaction-definition.ts b/packages/client/ui-trajectory/src/client/trajectory-compaction-definition.ts index 32916af141..3d16b6eb70 100644 --- a/packages/client/ui-trajectory/src/client/trajectory-compaction-definition.ts +++ b/packages/client/ui-trajectory/src/client/trajectory-compaction-definition.ts @@ -21,7 +21,7 @@ function checkpointId( readonly plugin?: unknown readonly compactionId?: unknown } - return source.kind === 'plugin' && source.plugin === 'compact' + return source.kind === 'compact-checkpoint' && typeof source.compactionId === 'string' && source.compactionId !== '' ? source.compactionId : undefined diff --git a/packages/client/ui-trajectory/src/client/trajectory-event-projection.ts b/packages/client/ui-trajectory/src/client/trajectory-event-projection.ts index c132e88747..0f3d538233 100644 --- a/packages/client/ui-trajectory/src/client/trajectory-event-projection.ts +++ b/packages/client/ui-trajectory/src/client/trajectory-event-projection.ts @@ -66,8 +66,6 @@ export function contextProducer(source: unknown): ContextProducerView { return { role: 'recall', label: joined(collect(record, 'references', 'label')) ?? kind } case 'agent-instructions': return { role: 'inject', label: joined(collect(record, 'changes', 'path')) ?? kind } - case 'plugin': - return { role: 'inject', label: readString(record, 'plugin') ?? kind } case 'skill-invocation': return { role: 'inject', label: readString(record, 'name') ?? kind } default: diff --git a/packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts b/packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts index 1faaeb3547..dd0e4c66d2 100644 --- a/packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts +++ b/packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts @@ -136,9 +136,13 @@ const trajectoryInboxDefinition: ConversationNodeDefinition = { const trajectoryMessageDefinition: ConversationNodeDefinition = { kind: 'trajectory-input-message', target: 'trajectory', - match: event => event.type === 'user/message' - ? { id: String(event.seq), role: 'start' } - : null, + match: (event) => { + // Developer history is persisted for V4; presentation is intentionally deferred. + if (event.type === 'developer/message') throw new Error('Trajectory developer messages are not supported yet') + return event.type === 'user/message' + ? { id: String(event.seq), role: 'start' } + : null + }, start: (_context, match, reader) => { if (match.event.type !== 'user/message') { throw new Error('trajectory-input-message start requires user/message') diff --git a/packages/client/ui-trajectory/src/client/trajectory-tool-definition.ts b/packages/client/ui-trajectory/src/client/trajectory-tool-definition.ts index 684688e86c..3d3c5d608a 100644 --- a/packages/client/ui-trajectory/src/client/trajectory-tool-definition.ts +++ b/packages/client/ui-trajectory/src/client/trajectory-tool-definition.ts @@ -48,16 +48,16 @@ function rootResult( previous?: RunningToolCall, ): ToolResultNode | undefined { if (match.event.type !== 'tool/result') return undefined - const result = match.event.data.message.content[0] + const message = match.event.data.message return { kind: 'tool-result', seq: match.event.seq, time: match.event.time, - callId: String(match.event.data.message.source.callId), + callId: String(message.source.callId), call: previous === undefined ? null : { name: previous.name, argsRaw: previous.argsRaw }, callTime: previous?.time ?? null, - content: result.content, - isError: result.isError === true, + content: message.content, + isError: message.isError === true, ...(match.event.data.error === undefined ? {} : { error: match.event.data.error }), meta: match.event.data.meta, subCalls: [], diff --git a/packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts b/packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts index 0a4db8aeb9..e54bdf4188 100644 --- a/packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts +++ b/packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts @@ -167,7 +167,7 @@ function systemMessage(text: string) { id: `system-${text}`, role: 'system', content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, + source: { kind: 'system-prompt' }, } } @@ -176,6 +176,13 @@ describe('Trajectory conversation Definitions', () => { expect(trajectoryViewDefinition.toolCallFocus?.('call-1')).toBe('call-1') }) + it('rejects developer history until presentation is implemented', () => { + expect(() => assembler([at(0, 'developer/message', { turn: 1, step: 1, message: { + id: 'developer', role: 'developer', source: { kind: 'tool-registry' }, + content: [{ type: 'tool-addition', toolName: 'search' }], + } }, { surfaceOp: 'append' })])).toThrow('developer messages are not supported yet') + }) + it('assembles streaming usage, preserves retry facts, and materializes interruption', () => { const value = assembler([ at(1, 'turn/start', { turn: 1 }), @@ -456,14 +463,11 @@ describe('Trajectory conversation Definitions', () => { step: 1, message: { id: 'result-root-a', - role: 'user', + role: 'tool', + toolCallId: 'root-a', source: { kind: 'tool', callId: 'root-a' }, - content: [{ - type: 'tool-result', - toolCallId: 'root-a', - content: [{ type: 'text', text: 'root failed' }], - isError: true, - }], + content: [{ type: 'text', text: 'root failed' }], + isError: true, }, error: { name: 'ToolError', code: 'failed' }, meta: { presentation: 'raw' }, @@ -513,7 +517,7 @@ describe('Trajectory conversation Definitions', () => { id: 'checkpoint', role: 'user', content: [{ type: 'text', text: 'summary checkpoint' }], - source: { kind: 'plugin', plugin: 'compact', compactionId: 'complete' }, + source: { kind: 'compact-checkpoint', compactionId: 'complete' }, }), at(4, 'compaction/end', { compactionId: 'complete', turn: null }), at(5, 'compaction/start', { compactionId: 'orphan', turn: null }), @@ -806,7 +810,7 @@ describe('Trajectory conversation Definitions', () => { at(11, 'step/start', { turn: 1, step: 3 }), at(12, 'user/message', { turn: 1, step: 3, id: 'summary', role: 'user', - content: [{ type: 'text', text: 'summary' }], source: { kind: 'plugin', plugin: 'compaction' }, + content: [{ type: 'text', text: 'summary' }], source: { kind: 'compact-checkpoint', compactionId: 'compaction-1' }, }, { surfaceOp: { op: 'replace', startSeq: 5, endSeq: 9 }, sourceEventSeqs: [5, 8, 9] }), at(13, 'request/header', { reason: 'series', header: { config: { provider: 'test', model: 'test' }, tools: [] }, @@ -859,7 +863,7 @@ describe('Trajectory conversation Definitions', () => { at(6, 'system/message', { turn: 1, step: 1, message: systemMessage('B') }, { surfaceOp: 'append' }), at(7, 'request/header', { reason: 'resume', header: { config: { provider: 'test', model: 'test' } } }), at(8, 'user/message', { - ...systemMessage('summary'), role: 'user', source: { kind: 'plugin', plugin: 'compaction' }, + ...systemMessage('summary'), role: 'user', source: { kind: 'compact-checkpoint', compactionId: 'compaction-1' }, }, { surfaceOp: { op: 'replace', startSeq: 2, endSeq: 6 } }), at(9, 'assistant/message', { turn: 1, step: 1, message: assistantMessage('reply', 'reply') }), ]) diff --git a/packages/client/ui-trajectory/tests/event-projection.client.spec.ts b/packages/client/ui-trajectory/tests/event-projection.client.spec.ts index 0405cd9cc5..75ccac4052 100644 --- a/packages/client/ui-trajectory/tests/event-projection.client.spec.ts +++ b/packages/client/ui-trajectory/tests/event-projection.client.spec.ts @@ -15,7 +15,7 @@ describe('Trajectory event projection', () => { .toEqual({ role: 'inject', label: 'AGENTS.md' }) expect(contextProducer({ kind: 'agent-instructions', changes: 'bad' }).label) .toBe('agent-instructions') - expect(contextProducer({ kind: 'plugin', plugin: 'p' }).label).toBe('p') + expect(contextProducer({ kind: 'p' }).label).toBe('p') expect(contextProducer({ kind: 'plugin', plugin: 1 }).label).toBe('plugin') expect(contextProducer({ kind: 'skill-invocation', name: 's' }).label).toBe('s') expect(contextProducer({ kind: 'future' }).label).toBe('future') diff --git a/packages/client/ui-trajectory/tests/views.client.spec.tsx b/packages/client/ui-trajectory/tests/views.client.spec.tsx index 6ac678d4ac..cec77bbb0b 100644 --- a/packages/client/ui-trajectory/tests/views.client.spec.tsx +++ b/packages/client/ui-trajectory/tests/views.client.spec.tsx @@ -172,7 +172,7 @@ function standaloneDuration(): Pick< /** Empty sessions-list hook; breadcrumbs therefore fall back to the raw id. */ function emptySessions() { const store = createSnapshotStore( - { ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {} }) + { ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {} }) return bindSnapshotSelector(store) } diff --git a/packages/client/ui-user-questions/tests/plan-review-panel.client.spec.tsx b/packages/client/ui-user-questions/tests/plan-review-panel.client.spec.tsx index 3e8c54f972..4daccc5a42 100644 --- a/packages/client/ui-user-questions/tests/plan-review-panel.client.spec.tsx +++ b/packages/client/ui-user-questions/tests/plan-review-panel.client.spec.tsx @@ -52,7 +52,7 @@ const sessionList = { ids: [SID], byId: { [SID]: { id: SID, displayTitle: 'Session', running: false, retainedBy: {}, blank: false, updatedAt: 0 } }, phase: 'ready' as const, - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, } const attentionState: AttentionState = new Map() diff --git a/packages/client/ui-user-questions/tests/user-questions-composer.client.spec.tsx b/packages/client/ui-user-questions/tests/user-questions-composer.client.spec.tsx index 464b664eea..e119213f65 100644 --- a/packages/client/ui-user-questions/tests/user-questions-composer.client.spec.tsx +++ b/packages/client/ui-user-questions/tests/user-questions-composer.client.spec.tsx @@ -50,7 +50,7 @@ const sessionList = { ids: [SID], byId: { [SID]: { id: SID, displayTitle: 'Session', running: false, retainedBy: {}, blank: false, updatedAt: 0 } }, phase: 'ready' as const, - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, } const attentionState: AttentionState = new Map() diff --git a/packages/client/ui-workflow-run/README.i18n.yaml b/packages/client/ui-workflow-run/README.i18n.yaml index b9860d366f..7b2feae40e 100644 --- a/packages/client/ui-workflow-run/README.i18n.yaml +++ b/packages/client/ui-workflow-run/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-workflow-run/README.md -README.md: 2f61cbee94414349030c67a45c03057f21fd9afe -README.zh.md: 94d90d057a119e1093ec014bad29f0f4fff82af6 +README.md: f48efe1f1525603a0f710f1a3fc6302cc14d109f +README.zh.md: 9fa6f59b6899aa353d50a39e73218e6ee8748417 diff --git a/packages/client/ui-workflow-run/README.md b/packages/client/ui-workflow-run/README.md index 2f61cbee94..f48efe1f15 100644 --- a/packages/client/ui-workflow-run/README.md +++ b/packages/client/ui-workflow-run/README.md @@ -29,7 +29,7 @@ A top-level workflow run through `dsh-tool-workflow` appears in the conversation ### Navigating the node -The run uses a 32-pixel row with persistent chevrons, an inline state dot, and status text; phases use disclosure rows with title and member count in the main area and a fixed aggregate-status tail; members use a 16-pixel dot slot, a truncating name area, and a fixed status column. Opening a member's child Session requires the member to be running, the child id to be in the ordinary Session list, the row to have `origin: 'subagent'`, its `parentId` to be the current Session, and the list row to still be running — remote, addressed-only, wrong-parent, or terminal rows remain non-interactive. +The run uses a 32-pixel row with persistent chevrons, an inline state dot, and status text; phases use disclosure rows with title and member count in the main area and a fixed aggregate-status tail; members use a 16-pixel dot slot, a truncating name area, and a fixed status column. Opening a member's child Session requires both member and child to be running, and the child must belong to the current Session's direct-child catalog. Child activity uses the unified UI status, falling back to the Session summary when unknown. Session summaries do not establish membership; absent, wrong-parent, or terminal catalog entries remain non-interactive. ### State and completion diff --git a/packages/client/ui-workflow-run/README.zh.md b/packages/client/ui-workflow-run/README.zh.md index 94d90d057a..9fa6f59b68 100644 --- a/packages/client/ui-workflow-run/README.zh.md +++ b/packages/client/ui-workflow-run/README.zh.md @@ -29,7 +29,7 @@ kind: "package-reference" ### 导航节点 -运行使用 32 像素行,带常驻 chevron、行内状态点与状态文字;阶段使用 disclosure 行,在主区显示标题与成员数、在固定尾部显示聚合状态;成员使用 16 像素状态点槽、会截断文本的名称区与固定状态列。打开成员的子会话需要成员仍在运行、子 id 位于普通会话列表、列表行为 `origin: 'subagent'`、`parentId` 等于当前会话,且列表行仍标记运行——远程、仅地址化、父级不符或终态的行都不可交互。 +运行使用 32 像素行,带常驻 chevron、行内状态点与状态文字;阶段使用 disclosure 行,在主区显示标题与成员数、在固定尾部显示聚合状态;成员使用 16 像素状态点槽、可省略名称区与固定状态列。打开成员的子 Session 需要成员与子级均在运行,且子级属于当前 Session 的直接子级目录。子级活动状态使用统一 UI status,未知时使用 Session 摘要。Session 摘要不建立成员关系;目录中缺失、父级不符或终态的条目不可交互。 ### 状态与完成 diff --git a/packages/client/ui-workflow-run/src/client/WorkflowRunPanel.tsx b/packages/client/ui-workflow-run/src/client/WorkflowRunPanel.tsx index 8cd4d768e6..ee98a85fbf 100644 --- a/packages/client/ui-workflow-run/src/client/WorkflowRunPanel.tsx +++ b/packages/client/ui-workflow-run/src/client/WorkflowRunPanel.tsx @@ -10,6 +10,7 @@ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots import type { SessionListState, SessionTarget } from '@deepseek-ai/dsh-api-session-controller/client' import { shallowEqual } from '@deepseek-ai/dsh-client-store' import type { SessionId } from '@deepseek-ai/dsh-session/types' +import type { SessionStatusSnapshot } from '@deepseek-ai/dsh-client-ui-session/client' import type { WorkflowRunKey } from './locales.ts' import type { WorkflowRunMemberData, WorkflowRunPhaseData, WorkflowRunStatus, @@ -183,17 +184,15 @@ function navigableMembers( sessions: SessionListState, phases: readonly WorkflowRunPhaseData[], parentId: SessionId, + statuses: SessionStatusSnapshot, ): readonly SessionId[] { - const ordinary = new Set(sessions.ids) + const catalog = sessions.projectionsBySession[parentId] const result: SessionId[] = [] for (const phase of phases) { for (const member of phase.members) { - const summary = sessions.byId[member.childId] + const child = catalog?.values.subagentCatalog?.find(entry => entry.id === member.childId) if (member.status === 'running' - && ordinary.has(member.childId) - && summary?.origin === 'subagent' - && summary.parentId === parentId - && summary.running) { + && child !== undefined && (statuses.get(child.id)?.running ?? sessions.byId[child.id]?.running) === true) { result.push(member.childId) } } @@ -341,7 +340,7 @@ function PhaseSection({ } /** Render one durable workflow run with status-driven run and phase disclosure. */ -export function WorkflowRunPanel({ node, sessionId, useSessions, openSession, t }: WorkflowRunPanelProps) { +export function WorkflowRunPanel({ node, sessionId, useSessions, useSessionStatus, openSession, t }: WorkflowRunPanelProps) { const phaseFacts = useMemo(() => node.data.phases.map(phase => ( [phase.key, phaseDisclosureFacts(phase)] as const )), [node.data.phases]) @@ -356,8 +355,9 @@ export function WorkflowRunPanel({ node, sessionId, useSessions, openSession, t })) const runContentRef = useRef(null) const phaseContentRefs = useRef(new Map()) + const statuses = useSessionStatus(value => value) const navigable = useSessions( - sessions => navigableMembers(sessions, node.data.phases, sessionId), + sessions => navigableMembers(sessions, node.data.phases, sessionId, statuses), shallowEqual, ) diff --git a/packages/client/ui-workflow-run/tests/workflow-run.client.spec.tsx b/packages/client/ui-workflow-run/tests/workflow-run.client.spec.tsx index 84b589c36e..5f7df5979e 100644 --- a/packages/client/ui-workflow-run/tests/workflow-run.client.spec.tsx +++ b/packages/client/ui-workflow-run/tests/workflow-run.client.spec.tsx @@ -304,7 +304,9 @@ const listState = (overrides: Partial = {}): SessionListState }, }, phase: 'ready', - subagentsByParent: {}, + projectionsBySession: { [PARENT_ID]: { state: 'ready', error: null, values: { subagentCatalog: [ + { createdAt: 1, id: CHILD_ID, mode: 'one-shot' }, + ] } } }, jobsBySession: {}, ...overrides, }) @@ -664,6 +666,10 @@ describe('WorkflowRunPanel', () => { it('defers normal completion collapse until focused member content loses focus', () => { const sessions = listState({ ids: [PARENT_ID, CHILD_ID, SECOND_ID], + projectionsBySession: { [PARENT_ID]: { state: 'ready', error: null, values: { subagentCatalog: [ + { createdAt: 1, id: CHILD_ID, mode: 'one-shot' }, + { createdAt: 1, id: SECOND_ID, mode: 'one-shot' }, + ] } } }, byId: { ...listState().byId, [SECOND_ID]: { @@ -825,12 +831,13 @@ describe('WorkflowRunPanel', () => { expect(screen.getByRole('button', { name: /未分阶段/ }).getAttribute('aria-expanded')).toBe('true') }) - it('opens only a running ordinary-list subagent proven to have this parent', () => { + it('opens a running member confirmed by the direct parent catalog', () => { const data: WorkflowRunChatData = { name: 'audit', status: 'running', phases: [phase()], } const openSession = vi.fn() - render() + const sessions = listState() + render() fireEvent.click(screen.getByRole('button', { name: '打开 worker' })) expect(openSession).toHaveBeenCalledWith({ parentSessionId: PARENT_ID, @@ -839,30 +846,40 @@ describe('WorkflowRunPanel', () => { }) }) - it('promotes a running member when its ordinary Session row arrives', () => { + it('uses observed running state for a catalog-only member', () => { + const data: WorkflowRunChatData = { name: 'audit', status: 'running', phases: [phase()] } + const sessions = listState({ + ids: [PARENT_ID], + byId: { ...listState().byId, [CHILD_ID]: { ...listState().byId[CHILD_ID]!, running: false } }, + }) + const openSession = vi.fn() + let statuses = new Map([[CHILD_ID, { running: true, pendingInteraction: undefined, completionUnread: false }]]) + const props: WorkflowRunPanelProps = { ...panelProps(data, sessions, openSession), + useSessionStatus: select => select(statuses), + } + const view = render() + fireEvent.click(screen.getByRole('button', { name: '打开 worker' })) + expect(openSession).toHaveBeenCalledWith({ parentSessionId: PARENT_ID, childSessionId: CHILD_ID, mode: 'one-shot' }) + statuses = new Map([[CHILD_ID, { running: false, pendingInteraction: undefined, completionUnread: false }]]) + view.rerender() + expect(screen.queryByRole('button', { name: '打开 worker' })).toBeNull() + }) + + it('promotes a running member when its parent catalog arrives', () => { const data: WorkflowRunChatData = { name: 'audit', status: 'running', phases: [phase()], } - const view = render() + const view = render() expect(screen.queryByRole('button', { name: '打开 worker' })).toBeNull() view.rerender() expect(screen.getByRole('button', { name: '打开 worker' })).toBeTruthy() }) it.each([ - ['not in ordinary list', listState({ ids: [PARENT_ID] }), 'running'], - ['remote row', listState({ byId: { - ...listState().byId, - [CHILD_ID]: { ...listState().byId[CHILD_ID]!, origin: undefined }, - } }), 'running'], - ['wrong parent', listState({ byId: { - ...listState().byId, - [CHILD_ID]: { ...listState().byId[CHILD_ID]!, parentId: 'other' as SessionId }, - } }), 'running'], - ['list terminal', listState({ byId: { - ...listState().byId, - [CHILD_ID]: { ...listState().byId[CHILD_ID]!, running: false }, - } }), 'running'], + ['catalog absent', listState({ projectionsBySession: {} }), 'running'], + ['catalog empty', listState({ projectionsBySession: { [PARENT_ID]: { state: 'ready', error: null, values: { subagentCatalog: [] } } } }), 'running'], + ['wrong parent', listState({ projectionsBySession: { ['other' as SessionId]: { state: 'ready', error: null, values: { subagentCatalog: [{ createdAt: 1, id: CHILD_ID, mode: 'one-shot' }] } } } }), 'running'], + ['child inactive', listState({ byId: { ...listState().byId, [CHILD_ID]: { ...listState().byId[CHILD_ID]!, running: false } } }), 'running'], ['member terminal', listState(), 'completed'], ] as const)('does not navigate when %s', (_name, sessions, memberStatus) => { const data: WorkflowRunChatData = { diff --git a/packages/client/ui-workspace/README.i18n.yaml b/packages/client/ui-workspace/README.i18n.yaml index b39d737103..fdcdf0ae9c 100644 --- a/packages/client/ui-workspace/README.i18n.yaml +++ b/packages/client/ui-workspace/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-workspace/README.md -README.md: 2f5ccee44e9d69eec45cf23bb8c368d67974eda7 -README.zh.md: 173129d6d03ccd6d3ccf9a4f72effae612711bcb +README.md: dc9ecee1df515f8e9b4183b6d97c29301c848652 +README.zh.md: 065f77ac442943b5683f0d492b56ab7d6668ba99 diff --git a/packages/client/ui-workspace/README.md b/packages/client/ui-workspace/README.md index 2f5ccee44e..dc9ecee1df 100644 --- a/packages/client/ui-workspace/README.md +++ b/packages/client/ui-workspace/README.md @@ -65,7 +65,7 @@ The value is intentionally best effort for cold Sessions. An identity-matching u ----- -`ctx.uiWorkspace.openSession(target)` synchronously replaces the owned `mainView` reference and returns the main area to Conversation without waiting for `reference.ready`, so history loading renders inside the selected Session view. The target may be a known Session id or a durable direct-parent subagent address; an explicit address does not require a preloaded parent catalog. `openWorkspace(id, beforeOpen?)` and `forkSession(id)` open their result only if no later navigation has superseded the request; New Session uses `openWorkspace`. The optional synchronous preparation callback runs after the target is retained and only for a current Workspace request, so superseded requests do not move composer drafts. Navigation or owner disposal suppresses the late UI commit, not the underlying Session creation. Archiving the main Session releases its reference and clears the main selection. Selection failure leaves a global panel visible. Session rows read `usePanelInfo` to suppress their selected appearance while a global panel is active; search and directory-picker focus alone do not leave that panel. +`ctx.uiWorkspace.openSession(target)` synchronously replaces the owned `mainView` reference and returns the main area to Conversation without waiting for `reference.ready`, so history loading renders inside the selected Session view. The target may be a known Session id or a durable direct-parent subagent address; an explicit address does not require a preloaded parent catalog. `openWorkspace(id, beforeOpen?)` and `forkSession(id)` open their result only if no later navigation has superseded the request; New Session uses `openWorkspace`. The optional synchronous preparation callback runs after the target is retained and only for a current Workspace request, so superseded requests do not move composer drafts. Navigation or owner disposal suppresses the late UI commit, not the underlying Session creation. Startup restoration retains its main reference without changing the selected panel or cancelling a later navigation. Archiving the main Session releases its reference and clears the main selection. Selection failure leaves a global panel visible. Session rows read `usePanelInfo` to suppress their selected appearance while a global panel is active; search and directory-picker focus alone do not leave that panel. New Session tries to acquire the first eligible blank in catalog order; startup restoration tries the saved blank. If that writer is held, navigation creates a new Session without trying other blanks. Other acquisition failures abort the request and are currently reported only to the console. Released blanks retain their slash-command state when reused. Later navigation cancels a pending startup selection. @@ -85,7 +85,7 @@ Each registration declares a **directory-flow child hole** (`single` kind: `conv Once the Workspace baseline is ready, browser-persisted expansion and Session-order records retain only current Workspace ids plus Ungrouped and the flat-list account. `WorkspaceView.sessionIds` supplies real-Workspace membership, not Session display order. View actions receive complete account orders, never filtered rows. A new member without a Session summary waits for that summary, while a saved position survives a temporarily missing summary. Archive visibility is applied only when deriving rows. Pin and drag writes save complete orders; ordinary derivation does not write them. The selected blank Session remains an explicit position write, including during Workspace reconnection, when other saved members are retained until the baseline establishes membership. Ordering remains mounted while the sidebar is a rail or search replaces its body. Last updated derives from current summaries without reading saved positions; equal timestamps use Session ids as a stable tie-break. -The sidebar hides durable summaries with `origin: 'subagent'`. Each visible ordinary row inherits the shared ongoing loader while any descendant reached through uninterrupted subagent-origin lineage is running. The same pure derivation reads the Schedule key from list projection values for grouped, flat, and search nodes; the package uses only the type-only `@deepseek-ai/dsh-schedule/client` dependency and does not import the Schedule runtime or `ui-schedule`. +The sidebar hides durable summaries with `origin: 'subagent'`. A visible ordinary row shows the shared ongoing loader from running direct children in its loaded parent catalog, never from summary lineage. Child activity uses the latest UI status, falling back to the Session summary until that status is known. The same pure derivation reads the Schedule key from list projection values for grouped, flat, and search nodes; the package uses only the type-only `@deepseek-ai/dsh-schedule/client` dependency and does not import the Schedule runtime or `ui-schedule`. Row motion belongs to [AnimatedRows](src/client/rows/AnimatedRows.tsx). It measures keyed rows before and after React commits that change their membership or order, and uses native movement and opacity animations. Removed rows fade as inert copies outside the scrolling list; they do not delay React unmounting or extend its scroll range. Initial loading, drag commits, overflow expansion, and view-option changes settle immediately. The animator has no layout observers or polling and does not measure content-only updates or scrolling. diff --git a/packages/client/ui-workspace/README.zh.md b/packages/client/ui-workspace/README.zh.md index 173129d6d0..065f77ac44 100644 --- a/packages/client/ui-workspace/README.zh.md +++ b/packages/client/ui-workspace/README.zh.md @@ -65,7 +65,7 @@ Session 行渲染运行时的实时 `pendingInteraction` 分类:审批显示** ----- -`ctx.uiWorkspace.openSession(target)` 会同步替换其拥有的 `mainView` reference,并让主区域返回 Conversation,而不等待 `reference.ready`,因此历史加载会显示在已经选中的 Session 视图内。目标可以是已知 Session id,也可以是持久的直接父子 subagent 地址;显式地址不要求预先加载 parent catalog。`openWorkspace(id, beforeOpen?)` 和 `forkSession(id)` 仅在请求未被后续导航替代时打开结果;新会话使用 `openWorkspace`。可选的同步准备回调在目标被 retain 后执行,并且仅对仍有效的 Workspace 请求执行,因此过期请求不会搬移 composer 草稿。后续导航或 owner 释放会阻止晚到的 UI 提交,但不取消底层 Session 创建。归档主 Session 会释放其 reference 并清除主选择。选择失败时保留当前全局面板。Session 行读取 `usePanelInfo`,在全局面板活跃时不显示 Session 选中样式;仅把焦点移到搜索框或目录选择器不会离开该面板。 +`ctx.uiWorkspace.openSession(target)` 会同步替换其拥有的 `mainView` reference,并让主区域返回 Conversation,而不等待 `reference.ready`,因此历史加载会显示在已经选中的 Session 视图内。目标可以是已知 Session id,也可以是持久的直接父子 subagent 地址;显式地址不要求预先加载 parent catalog。`openWorkspace(id, beforeOpen?)` 和 `forkSession(id)` 仅在请求未被后续导航替代时打开结果;新会话使用 `openWorkspace`。可选的同步准备回调在目标被 retain 后执行,并且仅对仍有效的 Workspace 请求执行,因此过期请求不会搬移 composer 草稿。后续导航或 owner 释放会阻止晚到的 UI 提交,但不取消底层 Session 创建。启动恢复会 retain 主 reference,不改变已选面板,也不取消后续导航。归档主 Session 会释放其 reference 并清除主选择。选择失败时保留当前全局面板。Session 行读取 `usePanelInfo`,在全局面板活跃时不显示 Session 选中样式;仅把焦点移到搜索框或目录选择器不会离开该面板。 新建会话尝试获取列表中第一个符合条件的空白会话;启动恢复尝试已保存的空白会话。若该写锁被占用,导航直接新建 Session,不再尝试其他空白会话。其他获取错误会中止请求,目前只报告到控制台。已释放的空白会话被复用时保留 slash 命令状态。后续导航会取消尚未完成的启动选择。 @@ -85,7 +85,7 @@ Session 行渲染运行时的实时 `pendingInteraction` 分类:审批显示** Workspace 基线就绪后,浏览器持久化的展开状态和 Session 顺序记录只保留当前 Workspace id、Ungrouped 和单列表记账。`WorkspaceView.sessionIds` 提供真实 Workspace 的成员关系,而不提供 Session 显示顺序。视图操作接收完整记账顺序,而不是筛选后的行。尚无 Session 摘要的新成员会等待摘要,已保存的位置则在摘要暂时缺失时保留。归档显隐仅在派生行时应用。置顶和拖拽写入完整顺序,普通派生不执行写入。当前选中的空白 Session 仍是一次显式位置写入;Workspace 重连时同样如此,此时保留其他已保存成员,直到基线确定成员关系。侧边栏收成窄栏或搜索替代列表主体时,排序仍保持挂载。最近更新从当前摘要派生,不读取已保存位置;时间相同时按 Session id 稳定排序。 -侧边栏隐藏持久化摘要中带有 `origin: 'subagent'` 的行。每个可见普通行都会在经不间断的 subagent 谱系可达的任一后代运行时继承共享 ongoing loading。同一项纯派生逻辑还会为分组、平铺与搜索节点读取列表 projection value 中的 Schedule key;本包只使用纯类型依赖 `@deepseek-ai/dsh-schedule/client`,不会导入 Schedule 运行时或 `ui-schedule`。 +侧边栏隐藏持久化摘要中带有 `origin: 'subagent'` 的行。可见普通行的共享 ongoing loading 来自其已加载 parent 目录中正在运行的直接 child,绝不来自摘要谱系。Child 活动状态使用最新 UI status,尚无该状态时使用 Session 摘要。同一项纯派生逻辑还会为分组、平铺与搜索节点读取列表 projection value 中的 Schedule key;本包只使用纯类型依赖 `@deepseek-ai/dsh-schedule/client`,不会导入 Schedule 运行时或 `ui-schedule`。 行动画由 [AnimatedRows](src/client/rows/AnimatedRows.tsx) 负责。它仅在 React 提交改变行成员或顺序时读取更新前后的位置,并使用浏览器原生位移与透明度动画。被移除的行以不可交互的副本在滚动列表外淡出,不会延迟 React 卸载,也不会扩大列表的滚动范围。初始加载、拖拽提交、展开其余会话和视图选项变化直接完成。动画组件不使用布局观察器或轮询,也不会因仅内容更新或滚动而测量位置。 diff --git a/packages/client/ui-workspace/src/client/navigation.ts b/packages/client/ui-workspace/src/client/navigation.ts index c0341186ad..82796c0b9c 100644 --- a/packages/client/ui-workspace/src/client/navigation.ts +++ b/packages/client/ui-workspace/src/client/navigation.ts @@ -174,20 +174,20 @@ class UiWorkspaceService extends Service implements UiWorkspace { } openSession(target: SessionTarget): void { - this.replaceMain(target, this.lifetime.signal) + this.replaceMain(target, this.lifetime.signal, 'reveal') } async openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise { const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]) const sessionId = await this.connectWorkspace(workspaceId) if (navigation.aborted) return - this.replaceMain(sessionId, navigation, beforeOpen) + this.replaceMain(sessionId, navigation, 'reveal', beforeOpen) } async forkSession(sessionId: SessionId): Promise { const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]) const childId = await this.sessions.fork({ sessionId, increaseTitle: true }) - if (!navigation.aborted) this.replaceMain(childId, navigation) + if (!navigation.aborted) this.replaceMain(childId, navigation, 'reveal') } startSession(workspaceId?: WorkspaceId): void { @@ -274,15 +274,15 @@ class UiWorkspaceService extends Service implements UiWorkspace { private async restoreSelection(workspaces: WorkspaceSnapshot, sessions: SessionListState): Promise { const saved = this.selection.getSnapshot() if (saved.subagentAddress !== undefined) { - void this.sessions.refreshSubagents(saved.subagentAddress.parentSessionId) - this.openSession(saved.subagentAddress) + void this.sessions.refreshProjections(saved.subagentAddress.parentSessionId) + this.replaceMain(saved.subagentAddress, this.lifetime.signal, 'preserve') return } const summary = saved.sessionId === undefined ? undefined : sessions.byId[saved.sessionId] const workspace = summary === undefined ? undefined : workspaces.items.find(item => item.sessionIds.includes(summary.id)) if (summary !== undefined && (!summary.blank || workspace === undefined)) { - this.openSession(summary.id) + this.replaceMain(summary.id, this.lifetime.signal, 'preserve') return } const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]) @@ -294,7 +294,7 @@ class UiWorkspaceService extends Service implements UiWorkspace { const target = workspace?.workspaceId ?? recentWorkspace(workspaces.items, sessions.byId) if (sessionId === undefined && target !== undefined) sessionId = await this.connectWorkspace(target) if (sessionId !== undefined && !navigation.aborted) { - this.replaceMain(sessionId, navigation) + this.replaceMain(sessionId, navigation, 'preserve') } } @@ -318,6 +318,7 @@ class UiWorkspaceService extends Service implements UiWorkspace { private replaceMain( target: SessionTarget, signal: AbortSignal, + panel: 'reveal' | 'preserve', beforeOpen?: (sessionId: SessionId) => void, ): void { signal.throwIfAborted() @@ -343,8 +344,8 @@ class UiWorkspaceService extends Service implements UiWorkspace { const previous = this.mainReference this.mainReference = reference previous?.release() - void this.sessions.refreshSubagents(reference.sessionId) - this.ctx.layout.selectPanel(null) + void this.sessions.refreshProjections(reference.sessionId) + if (panel === 'reveal') this.ctx.layout.selectPanel(null) } } diff --git a/packages/client/ui-workspace/src/client/subagent-lineage.ts b/packages/client/ui-workspace/src/client/subagent-lineage.ts deleted file mode 100644 index bd145d723a..0000000000 --- a/packages/client/ui-workspace/src/client/subagent-lineage.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** UI Workspace-owned projection of descendant counts from Session summaries. */ - -import type { SessionId } from '@deepseek-ai/dsh-session/types' - -interface LineageEntry { - readonly id: SessionId - readonly parentId?: SessionId - readonly origin?: 'subagent' - readonly running: boolean -} - -/** Descendant counts for one possible parent Session. */ -export interface SubagentDescendantSummary { - readonly count: number - readonly runningCount: number -} - -/* jscpd:ignore-start -- UI Subagent and UI Workspace independently project their own views. */ -/** - * Index uninterrupted subagent descendants under each ancestor. - * @param summaries - Session summaries keyed by id. - * @returns descendant totals keyed by possible parent id. - */ -export function indexSubagentDescendants( - summaries: Readonly>, -): ReadonlyMap { - const indexed = new Map() - for (const descendant of Object.values(summaries)) { - if (descendant.origin !== 'subagent') continue - const seen = new Set() - let current: LineageEntry | undefined = descendant - while (current?.origin === 'subagent' && current.parentId !== undefined && !seen.has(current.id)) { - seen.add(current.id) - const aggregate = indexed.get(current.parentId) - if (aggregate === undefined) { - indexed.set(current.parentId, { count: 1, runningCount: descendant.running ? 1 : 0 }) - } else { - aggregate.count += 1 - if (descendant.running) aggregate.runningCount += 1 - } - current = summaries[current.parentId] - } - } - return indexed -} -/* jscpd:ignore-end */ diff --git a/packages/client/ui-workspace/src/client/tree.ts b/packages/client/ui-workspace/src/client/tree.ts index 5b17222765..6950c15a4e 100644 --- a/packages/client/ui-workspace/src/client/tree.ts +++ b/packages/client/ui-workspace/src/client/tree.ts @@ -14,9 +14,6 @@ import type {} from '@deepseek-ai/dsh-schedule/client' import type { SessionId } from '@deepseek-ai/dsh-session/types' import { assertNever } from '@deepseek-ai/dsh-util-values' import { workspaceTitleOf } from '@deepseek-ai/dsh-util-workspace-path' -import { - indexSubagentDescendants, type SubagentDescendantSummary, -} from './subagent-lineage.ts' /** Group key for Sessions outside every Workspace. */ export const UNGROUPED_KEY = '' @@ -54,7 +51,7 @@ export interface SessionNode { /** A Session-scoped UI consumer is awaiting this user. */ pendingInteraction?: SessionPendingInteractionStatus running: boolean - /** Running descendants connected through uninterrupted subagent-origin lineage. */ + /** Running direct children in the loaded subagent catalog. */ runningSubagentCount: number /** Finished running while not selected and not yet opened (the green "done" reminder dot). */ completed: boolean @@ -97,7 +94,7 @@ export interface SearchResultNode { /** A Session-scoped UI consumer is awaiting this user. */ pendingInteraction?: SessionPendingInteractionStatus running: boolean - /** Running descendants connected through uninterrupted subagent-origin lineage. */ + /** Running direct children in the loaded subagent catalog. */ runningSubagentCount: number /** Finished running while not selected and not yet opened (the green "done" reminder dot). */ completed: boolean @@ -384,9 +381,16 @@ function visiblePendingKind(kind: string | undefined): SessionPendingInteraction } } +function runningChildCount(list: SessionListState, parentId: SessionId, statuses: SessionStatuses): number { + return list.projectionsBySession[parentId]?.values.subagentCatalog?.reduce( + (count, child) => count + ((statuses.get(child.id)?.running ?? list.byId[child.id]?.running) === true ? 1 : 0), + 0, + ) ?? 0 +} + function sessionNode( s: SessionSummary, - descendants: ReadonlyMap, + list: SessionListState, statuses: SessionStatuses, pinned: ReadonlySet, archived: ReadonlySet, @@ -398,7 +402,7 @@ function sessionNode( title: sessionTitle(s), blank: s.blank, running: status?.running ?? s.running, - runningSubagentCount: descendants.get(s.id)?.runningCount ?? 0, + runningSubagentCount: runningChildCount(list, s.id, statuses), completed: status?.completionUnread === true, hasActiveSchedule: hasActiveSchedule(s), pinned: !archived.has(s.id) && pinned.has(s.id), @@ -433,7 +437,6 @@ export function deriveGroups( const archived = new Set(rowState.archivedSessionIds) const pinned = new Set(rowState.pinnedSessionIds) const expandedGroups = new Set(view.expandedGroups) - const descendants = indexSubagentDescendants(list.byId) const current = mainSessionId(list) const currentGroup = current === undefined ? undefined @@ -452,7 +455,7 @@ export function deriveGroups( containsCurrent: g.key === currentGroup, sessions: expanded ? sectionMembers(g.sessions, pinned, archived) - .map(session => sessionNode(session, descendants, statuses, pinned, archived)) + .map(session => sessionNode(session, list, statuses, pinned, archived)) : [], }) } @@ -505,7 +508,6 @@ export function deriveFlat( ): SessionNode[] { const archived = new Set(rowState.archivedSessionIds) const pinned = new Set(rowState.pinnedSessionIds) - const descendants = indexSubagentDescendants(list.byId) const current = mainSessionId(list) const members = sessionIds.flatMap((id) => { const session = list.byId[id] @@ -514,7 +516,7 @@ export function deriveFlat( : [] }) return sectionMembers(members, pinned, archived) - .map(session => sessionNode(session, descendants, statuses, pinned, archived)) + .map(session => sessionNode(session, list, statuses, pinned, archived)) } /** @@ -544,7 +546,6 @@ export function deriveSearchResults( const q = query.trim().toLowerCase() if (q === '') return { items: [], hasMore: false } const archived = new Set(archivedSessionIds) - const descendants = indexSubagentDescendants(list.byId) const current = mainSessionId(list) const workspaceBySession = new Map() @@ -600,7 +601,7 @@ export function deriveSearchResults( title: sessionTitle(summary), workspace: labelOf(summary), running: status?.running ?? summary.running, - runningSubagentCount: descendants.get(summary.id)?.runningCount ?? 0, + runningSubagentCount: runningChildCount(list, summary.id, statuses), ...(pendingInteraction === undefined ? {} : { pendingInteraction }), diff --git a/packages/client/ui-workspace/tests/apply.client.spec.ts b/packages/client/ui-workspace/tests/apply.client.spec.ts index 72d0b3d7c5..507dadb724 100644 --- a/packages/client/ui-workspace/tests/apply.client.spec.ts +++ b/packages/client/ui-workspace/tests/apply.client.spec.ts @@ -62,8 +62,8 @@ async function bench() { ctx.provide('sessions', { list: { getSnapshot: () => ({ - ids: [], byId: {}, current: undefined, phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, currentAddress: undefined, + ids: [], byId: {}, phase: 'ready', + projectionsBySession: {}, jobsBySession: {}, }), subscribe, }, @@ -74,7 +74,7 @@ async function bench() { searchResultLimit: 20, binding, subagentAddress: vi.fn(() => undefined), - refreshSubagents: vi.fn(() => Promise.resolve()), + refreshProjections: vi.fn(() => Promise.resolve()), fork, } as never) const pickDirectory = vi.fn(() => Promise.resolve({ ok: true as const, value: '/projects/picked' })) diff --git a/packages/client/ui-workspace/tests/subagent-lineage.client.spec.ts b/packages/client/ui-workspace/tests/subagent-lineage.client.spec.ts deleted file mode 100644 index cefcad61c2..0000000000 --- a/packages/client/ui-workspace/tests/subagent-lineage.client.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { SessionId } from '@deepseek-ai/dsh-session/types' -import { indexSubagentDescendants } from '../src/client/subagent-lineage.ts' - -const sid = (id: string): SessionId => id as SessionId - -describe('UI Workspace descendant projection', () => { - it('counts nested running descendants and stops at ordinary forks', () => { - const root = { id: sid('root'), running: false } - const child = { id: sid('child'), parentId: root.id, origin: 'subagent' as const, running: true } - const leaf = { id: sid('leaf'), parentId: child.id, origin: 'subagent' as const, running: false } - const fork = { id: sid('fork'), parentId: child.id, running: false } - const result = indexSubagentDescendants(Object.fromEntries( - [root, child, leaf, fork].map(item => [item.id, item]), - )) - expect(result.get(root.id)).toEqual({ count: 2, runningCount: 1 }) - expect(result.get(child.id)).toEqual({ count: 1, runningCount: 0 }) - expect(result.has(fork.id)).toBe(false) - }) - - it('terminates cycles and retains missing-parent aggregates', () => { - const a = { id: sid('a'), parentId: sid('b'), origin: 'subagent' as const, running: false } - const b = { id: sid('b'), parentId: sid('a'), origin: 'subagent' as const, running: false } - const orphan = { id: sid('orphan'), parentId: sid('missing'), origin: 'subagent' as const, running: true } - const result = indexSubagentDescendants({ [a.id]: a, [b.id]: b, [orphan.id]: orphan }) - expect(result.get(a.id)?.count).toBe(2) - expect(result.get(b.id)?.count).toBe(2) - expect(result.get(sid('missing'))).toEqual({ count: 1, runningCount: 1 }) - }) -}) diff --git a/packages/client/ui-workspace/tests/tree.client.spec.ts b/packages/client/ui-workspace/tests/tree.client.spec.ts index 94262a791d..d37bddd386 100644 --- a/packages/client/ui-workspace/tests/tree.client.spec.ts +++ b/packages/client/ui-workspace/tests/tree.client.spec.ts @@ -6,6 +6,7 @@ import type { } from '@deepseek-ai/dsh-client-ui-session/client' import type { ScheduleId, ScheduleRecord } from '@deepseek-ai/dsh-schedule/client' import type { SessionId } from '@deepseek-ai/dsh-session/types' +import type { SessionProjectionSnapshot } from '@deepseek-ai/dsh-api-session-controller/client' import { type ArchivedFilter, deriveFlat, deriveGroups, deriveSearchResults, orderByRecency, owningGroupKey, owningParentFolder, @@ -22,7 +23,15 @@ const summary = (id: string, updatedAt: number, cwd?: string): SessionSummary => const list = (...items: SessionSummary[]): SessionListState => ({ ids: items.map(item => item.id), byId: Object.fromEntries(items.map(item => [item.id, item])), - phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + phase: 'ready', projectionsBySession: {}, jobsBySession: {}, +}) +const catalog = (...ids: string[]): SessionProjectionSnapshot => ({ + values: { subagentCatalog: ids.map(id => ({ + id: sid(id), mode: 'continuable', label: id, + createdAt: 1, + })) }, + state: 'ready', + error: null, }) const withMain = (state: SessionListState, id: SessionId): SessionListState => ({ ...state, @@ -302,7 +311,7 @@ describe('deriveGroups', () => { ).items.map(node => [node.id, node.hasActiveSchedule])).toEqual(expected) }) - it('hides subagent-origin sessions without hiding ordinary forks', () => { + it('hides subagent-origin sessions and reads direct running counts from catalogs', () => { const parent = summary('parent', 1) const subagent = { ...summary('subagent', 3), parentId: parent.id, origin: 'subagent' as const, running: true, @@ -314,7 +323,17 @@ describe('deriveGroups', () => { const forkChild = { ...summary('fork-child', 5), parentId: fork.id, origin: 'subagent' as const, running: true, } - const sessions = { ...list(parent, fork, subagent, grandchild, forkChild), current: subagent.id } + const sessions = { + ...withMain(list(parent, fork, subagent, grandchild, forkChild), subagent.id), + projectionsBySession: { + [parent.id]: catalog( + 'subagent', + 'inactive-child', + ), + [fork.id]: catalog('fork-child'), + [subagent.id]: catalog('grandchild'), + }, + } const groups = deriveGroups( sessions, [workspace('first', ['parent', 'fork', 'subagent', 'grandchild', 'fork-child'])], @@ -325,16 +344,42 @@ describe('deriveGroups', () => { expect(groups[0]!.sessions.map(node => node.id)).toEqual([parent.id, fork.id]) expect(groups[0]!.sessionCount).toBe(2) - expect(groups[0]!.sessions[0]).toMatchObject({ running: false, runningSubagentCount: 2 }) + expect(groups[0]!.sessions[0]).toMatchObject({ running: false, runningSubagentCount: 1 }) expect(groups[0]!.sessions[1]).toMatchObject({ running: false, runningSubagentCount: 1 }) expect(deriveFlat(sessions, visibleSessionIds(sessions, noArchive, 'default'), noRows, noAttention) .map(node => [node.id, node.runningSubagentCount])).toEqual([ - [parent.id, 2], [fork.id, 1], + [parent.id, 1], [fork.id, 1], ]) expect(deriveSearchResults( sessions, [workspace('first', ['parent', 'fork'])], 'parent', noArchive, 'default', noAttention, { items: [], hasMore: false }, 10, - ).items[0]).toMatchObject({ id: parent.id, runningSubagentCount: 2 }) + ).items[0]).toMatchObject({ id: parent.id, runningSubagentCount: 1 }) + }) + + it('uses current child status only for members of the direct parent catalog', () => { + const parent = summary('parent', 1) + const child = { ...summary('child', 2), running: false } + const stopped = { ...summary('stopped', 3), running: true } + const unrelated = { ...summary('unrelated', 4), parentId: parent.id, running: true } + const sessions = { + ...list(parent, child, stopped, unrelated), + projectionsBySession: { + [parent.id]: catalog('child', 'stopped'), + }, + } + const statuses = new Map([ + [child.id, status(undefined, { running: true })], + [stopped.id, status(undefined, { running: false })], + [unrelated.id, status(undefined, { running: true })], + ]) + const counts = (snapshot: SessionStatusSnapshot) => [ + deriveGroups(sessions, [workspace('first', ['parent'])], noRows, snapshot, view(['first']))[0]!.sessions[0]!.runningSubagentCount, + deriveFlat(sessions, [parent.id], noRows, snapshot)[0]!.runningSubagentCount, + deriveSearchResults(sessions, [], 'parent', noArchive, 'default', snapshot, { items: [], hasMore: false }, 10).items[0]!.runningSubagentCount, + ] + expect(counts(statuses)).toEqual([1, 1, 1]) + statuses.set(child.id, status(undefined, { running: false })) + expect(counts(statuses)).toEqual([0, 0, 0]) }) it('ignores fork lineage and sorts every ungrouped session as a top-level row', () => { diff --git a/packages/client/ui-workspace/tests/workspace-browser.client.spec.tsx b/packages/client/ui-workspace/tests/workspace-browser.client.spec.tsx index 50f0557ba2..bd5d1ad4e2 100644 --- a/packages/client/ui-workspace/tests/workspace-browser.client.spec.tsx +++ b/packages/client/ui-workspace/tests/workspace-browser.client.spec.tsx @@ -49,7 +49,7 @@ const sessionState = ( ids: items.map(item => item.id), byId: Object.fromEntries(items.map(item => [item.id, item])), phase: 'ready', - subagentsByParent: {}, jobsBySession: {}, + projectionsBySession: {}, jobsBySession: {}, ...stateOverrides, } if (main === undefined) return state diff --git a/packages/client/ui-workspace/tests/workspace-picker.client.spec.tsx b/packages/client/ui-workspace/tests/workspace-picker.client.spec.tsx index 456109a2dd..9ff0181207 100644 --- a/packages/client/ui-workspace/tests/workspace-picker.client.spec.tsx +++ b/packages/client/ui-workspace/tests/workspace-picker.client.spec.tsx @@ -35,7 +35,7 @@ function hook(snapshot: T) { return function select(selector: (state: T) => S): S { return selector(snapshot) } } const sessions: SessionListState = { - ids: [], byId: {}, phase: 'ready', subagentsByParent: {}, jobsBySession: {}, + ids: [], byId: {}, phase: 'ready', projectionsBySession: {}, jobsBySession: {}, } const noPendingInteraction: SessionStatusSnapshot = new Map() const workspaceState = (items: readonly WorkspaceView[]): WorkspaceSnapshot => ({ diff --git a/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts b/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts index e533c9397c..625784bb5b 100644 --- a/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts +++ b/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts @@ -75,7 +75,7 @@ function sessionState( ids: summaries.map(item => item.id), byId: Object.fromEntries(summaries.map(item => [item.id, item])), phase, - subagentsByParent: {}, + projectionsBySession: {}, jobsBySession: {}, } } @@ -133,7 +133,7 @@ class FakeSessions implements ISessions { readonly create: ReturnType> readonly fork = vi.fn(async () => sid('forked')) readonly retained: RetainedSession[] = [] - readonly refreshSubagents = vi.fn(() => Promise.resolve()) + readonly refreshProjections = vi.fn(() => Promise.resolve()) readonly retain = vi.fn((target) => { const release = vi.fn<() => void>() const sessionId = typeof target === 'string' ? target : target.childSessionId @@ -152,7 +152,6 @@ class FakeSessions implements ISessions { declare readonly using: ISessions['using'] declare readonly retainInfo: ISessions['retainInfo'] declare readonly searchResultLimit: ISessions['searchResultLimit'] - declare readonly setSubagentCatalogOpen: ISessions['setSubagentCatalogOpen'] declare readonly refresh: ISessions['refresh'] declare readonly search: ISessions['search'] declare readonly scope: ISessions['scope'] @@ -278,7 +277,7 @@ describe('UiWorkspaceService', () => { b.uiWorkspace.openSession(sid('target')) expect(b.selectPanel).toHaveBeenCalledWith(null) expect(b.sessions.retain).toHaveBeenCalledWith(sid('target'), { source: 'mainView' }) - expect(b.sessions.refreshSubagents).toHaveBeenCalledWith(sid('target')) + expect(b.sessions.refreshProjections).toHaveBeenCalledWith(sid('target')) }) it('keeps the current panel when retaining the target fails', () => { @@ -673,6 +672,34 @@ describe('UiWorkspaceService', () => { expect(b.sessions.retain.mock.calls.map(([target]) => target)).toEqual([sid('chosen')]) }) + it('keeps a chosen panel and pending navigation when initial connection finishes', async () => { + const created = Promise.withResolvers() + const b = bench({ + workspaces: workspaceState([workspace('a')]), + sessions: sessionState(), + configureSessions: (sessions) => { sessions.create.mockReturnValueOnce(created.promise) }, + }) + const panel = 'other-panel' as MainPanelId + b.layout.selectPanel(panel) + const navigation = b.layout.beginNavigation() + created.resolve(sid('restored')) + await b.uiWorkspace.connectWorkspace(wid('a')) + expect(b.sessions.retained).toHaveLength(0) + expect(b.selectPanel.mock.calls).toEqual([[panel]]) + expect(navigation.aborted).toBe(false) + }) + + it('keeps a chosen panel when the saved target becomes discoverable', () => { + const saved = sid('saved') + persistSelection({ sessionId: saved }) + const b = bench({ workspaces: workspaceState(), sessions: sessionState([], 'pending') }) + const panel = 'other-panel' as MainPanelId + b.layout.selectPanel(panel) + b.sessions.list.set(sessionState([summary('saved')])) + expect(b.sessions.retained[0]!.reference.sessionId).toBe(saved) + expect(b.selectPanel.mock.calls).toEqual([[panel]]) + }) + it('restores a persisted subagent address without a parent catalog', () => { const address: SubagentAddress = { parentSessionId: sid('parent'), @@ -687,7 +714,7 @@ describe('UiWorkspaceService', () => { }) expect(b.sessions.retain).toHaveBeenCalledExactlyOnceWith(address, { source: 'mainView' }) - expect(b.sessions.refreshSubagents.mock.calls).toEqual([ + expect(b.sessions.refreshProjections.mock.calls).toEqual([ [address.parentSessionId], [address.childSessionId], ]) diff --git a/packages/compaction/compaction-basic/README.i18n.yaml b/packages/compaction/compaction-basic/README.i18n.yaml index fba8635a73..51b885763b 100644 --- a/packages/compaction/compaction-basic/README.i18n.yaml +++ b/packages/compaction/compaction-basic/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/compaction/compaction-basic/README.md -README.md: 68d5a321e04a90bfb726392d1fb179612f6e0626 -README.zh.md: f941cac74053a680cad859b68c7836e181065bc9 +README.md: cb31438816088070fe996e7f3d38b8480404aa84 +README.zh.md: a038fecc9880160a4fc23377cd5fec6e931a7b01 diff --git a/packages/compaction/compaction-basic/README.md b/packages/compaction/compaction-basic/README.md index 68d5a321e0..cb31438816 100644 --- a/packages/compaction/compaction-basic/README.md +++ b/packages/compaction/compaction-basic/README.md @@ -115,7 +115,7 @@ Pressure policy resolves capacity from the adapter that owns the durable route. ### Summarization mechanics -A direct `ctx.llm.stream()` call uses the configured provider/model pair and cap, falling back to the latest logged request target and then the `AgentOptions` pair, without running the loop-only `agent/request` extension point. The call replays the derived `system/message` at surface node 0 as the leading entry of `messages`, followed by the shadowed-region messages (including a shadowed in-history `system/message` in its surface position), and carries the header's tools verbatim — including image references, which the selected adapter must resolve or explicitly reject — and appends the compaction instruction as the final user message, so it reuses the provider's warm prefix cache instead of invalidating it. An empty-content system head contributes no message but remains outside the compacted range. The call sets `GenerateOptions.purpose` to `compaction`; only returned text enters the checkpoint, excluding reasoning and tool calls. Image output fails with `UNSUPPORTED_CONTENT` rather than disappearing. The replacement user message frames the summary with `` tags; the raw summary remains on the `compaction/summary` event. +A direct `ctx.llm.stream()` call uses the configured provider/model pair and cap, falling back to the latest logged request target and then the `AgentOptions` pair, without running the loop-only `agent/request` extension point. The call replays the derived `system/message` at surface node 0 as the leading entry of `messages`, followed by the shadowed-region messages (including a shadowed in-history `system/message` in its surface position), and carries the header's tools verbatim — including image references, which the selected adapter must resolve or explicitly reject — and appends the compaction instruction as the final user message, so it reuses the provider's warm prefix cache instead of invalidating it. An empty-content system head contributes no message but remains outside the compacted range. The final instruction is a frozen `RequestUserInput` without durable identity or source; the replayed history and persisted checkpoint remain durable messages. The call sets `GenerateOptions.purpose` to `compaction`; only returned text enters the checkpoint, excluding reasoning and tool calls. Image output fails with `UNSUPPORTED_CONTENT` rather than disappearing. The replacement user message frames the summary with `` tags; the raw summary remains on the `compaction/summary` event. ### The region transaction diff --git a/packages/compaction/compaction-basic/README.zh.md b/packages/compaction/compaction-basic/README.zh.md index f941cac740..a038fecc98 100644 --- a/packages/compaction/compaction-basic/README.zh.md +++ b/packages/compaction/compaction-basic/README.zh.md @@ -115,7 +115,7 @@ kind: "package-reference" ### 摘要机制 -直接 `ctx.llm.stream()` 调用使用已配置的提供方/模型对与上限,回退到最新已记录请求目标,然后再回退到 `AgentOptions` 对,而不运行仅用于 agent loop 的 `agent/request` 扩展点。该调用将 surface 节点 0 处派生的 `system/message` 作为 `messages` 的首项回放,后接已遮蔽区域消息(包括位于其 surface 位置的被遮蔽历史内 `system/message`),并逐字携带 header 的工具——包括所选适配器必须解析或明确拒绝的图片引用——并将压缩指令作为最后一条 user 消息追加,从而复用提供方的热前缀 cache,而非使它失效。空内容系统头节点不贡献消息,但仍处于压缩范围之外。调用将 `GenerateOptions.purpose` 设为 `compaction`;只有返回文本进入检查点,推理与工具调用都会被排除。图片输出会以 `UNSUPPORTED_CONTENT` 失败,而不是消失。替换 user 消息用 `` 标签框定摘要;原始摘要保留在 `compaction/summary` 事件上。 +直接 `ctx.llm.stream()` 调用使用已配置的提供方/模型对与上限,回退到最新已记录请求目标,然后再回退到 `AgentOptions` 对,而不运行仅用于 agent loop 的 `agent/request` 扩展点。该调用将 surface 节点 0 处派生的 `system/message` 作为 `messages` 的首项回放,后接已遮蔽区域消息(包括位于其 surface 位置的被遮蔽历史内 `system/message`),并逐字携带 header 的工具——包括所选适配器必须解析或明确拒绝的图片引用——并将压缩指令作为最后一条 user 消息追加,从而复用提供方的热前缀 cache,而非使它失效。空内容系统头节点不贡献消息,但仍处于压缩范围之外。最终指令是冻结的 `RequestUserInput`,不含持久身份或来源;回放历史和持久化检查点仍然使用持久消息。调用将 `GenerateOptions.purpose` 设为 `compaction`;只有返回文本进入检查点,推理与工具调用都会被排除。图片输出会以 `UNSUPPORTED_CONTENT` 失败,而不是消失。替换 user 消息用 `` 标签框定摘要;原始摘要保留在 `compaction/summary` 事件上。 ### 区域事务 diff --git a/packages/compaction/compaction-basic/src/region.ts b/packages/compaction/compaction-basic/src/region.ts index b4ba4ae380..7b3d77d299 100644 --- a/packages/compaction/compaction-basic/src/region.ts +++ b/packages/compaction/compaction-basic/src/region.ts @@ -23,7 +23,6 @@ import { SessionSeq, type Session, type SessionEvent } from '@deepseek-ai/dsh-se import type { Agent } from '@deepseek-ai/dsh-agent' import { frameSummary } from './summarizer.ts' import type { SummarizationInput, SummaryResult } from './summarizer.ts' - interface RegionDependencies { readonly meter: TokenMeter summarize(input: SummarizationInput, agent: Agent, signal?: AbortSignal): Promise diff --git a/packages/compaction/compaction-basic/src/summarizer.ts b/packages/compaction/compaction-basic/src/summarizer.ts index e015bf887d..2b85f6470e 100644 --- a/packages/compaction/compaction-basic/src/summarizer.ts +++ b/packages/compaction/compaction-basic/src/summarizer.ts @@ -5,9 +5,10 @@ */ import type { Context } from '@deepseek-ai/cordis' -import { contentHasImage, createUserMessage, BlockAssembler, LlmError } from '@deepseek-ai/dsh-llm' +import { contentHasImage, BlockAssembler, LlmError } from '@deepseek-ai/dsh-llm' +import { deepFreeze } from '@deepseek-ai/dsh-util-values' import type { - ContentBlock, FinishReason, GenerateOptions, Message, TokenUsage, ToolSchema, + ContentBlock, FinishReason, GenerateOptions, Message, RequestMessage, TokenUsage, ToolSchema, } from '@deepseek-ai/dsh-llm' import type { Agent } from '@deepseek-ai/dsh-agent' @@ -141,11 +142,11 @@ export async function summarizeWithLlm( } const assembler = new BlockAssembler() - const messages: Message[] = [ + const messages: RequestMessage[] = [ ...input.messages, - createUserMessage({ + deepFreeze({ + role: 'user', content: [{ type: 'text', text: COMPACTION_INSTRUCTION }], - source: { kind: 'plugin', plugin: 'dsh-compaction-basic' }, }), ] const options: GenerateOptions = { diff --git a/packages/compaction/compaction-basic/tests/compaction-basic.spec.ts b/packages/compaction/compaction-basic/tests/compaction-basic.spec.ts index bd6a48af66..9c36961f81 100644 --- a/packages/compaction/compaction-basic/tests/compaction-basic.spec.ts +++ b/packages/compaction/compaction-basic/tests/compaction-basic.spec.ts @@ -14,6 +14,7 @@ import { } from '@deepseek-ai/dsh-compaction-basic/src/config.ts' import type { CompactionResult } from '@deepseek-ai/dsh-compaction' import LlmRuntime, { createUserMessage, ToolCallId, CONTEXT_WINDOW_EXCEEDED_CODE, createSystemMessage, createToolResultMessage, LlmAdapter , createMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import type { ContentBlock, GenerateOptions, @@ -29,6 +30,12 @@ import TokenMeter from '@deepseek-ai/dsh-token-meter' import { agentEvents, type Agent, type RequestErrorAction } from '@deepseek-ai/dsh-agent' import ToolResultPruner from '@deepseek-ai/dsh-compaction-tool-result-pruner' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const SIGNAL = new AbortController().signal const MODEL = 'test-model' @@ -89,26 +96,21 @@ function agent(session: Session, model?: string): Agent { } as Agent } -/** Flatten every text fragment the summarizer received, recursing tool-result blocks. */ +/** Flatten every text fragment the summarizer received across all messages. */ function summarizedText(input: SummarizationInput): string { - const collect = (blocks: readonly ContentBlock[]): string => - blocks.map(block => - block.type === 'text' ? block.text - : block.type === 'tool-result' ? collect(block.content) - : '').join('\n') - return input.messages.map(message => collect(message.content)).join('\n') + return input.messages.flatMap(message => message.content) + .map(block => block.type === 'text' ? block.text : '') + .join('\n') } /** A minimal replayed prefix carrying one user message of the given text. */ function promptInput(text: string): SummarizationInput { return { messages: [createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })] } } -const SYSTEM_PROMPT_PLUGIN = '@deepseek-ai/dsh-system-prompt' - /** * Closed two-message turns followed by one open turn for durable compaction events. * A `system` text puts a `system/message` at surface node 0 before turn 1's user message. @@ -121,7 +123,7 @@ function conversation(turns = 4, text = 'fixture '.repeat(40).trim(), system?: s session.append('system/message', { turn, step: 1, - message: createSystemMessage(system, SYSTEM_PROMPT_PLUGIN), + message: createSystemMessage(system), }, { surfaceOp: 'append' }) } session.append('user/message', createUserMessage({ @@ -774,8 +776,8 @@ describe('pressure measurement and retention', () => { for (const message of messages) { for (const block of message.content) { if (block.type === 'tool-call') calls.add(block.id) - if (block.type === 'tool-result') expect(calls.has(block.toolCallId)).toBe(true) } + if (message.role === 'tool') expect(calls.has(message.toolCallId)).toBe(true) } }) @@ -890,7 +892,7 @@ describe('optional model-free tool-result pruning', () => { expect(await compactIfNeeded(compact, session)).not.toBeNull() expect(compact.calls).toHaveLength(1) const original = session.snapshotEvents().find(event => event.type === 'tool/result') - expect(original?.type === 'tool/result' && original.data.message.content[0].content[0]) + expect(original?.type === 'tool/result' && original.data.message.content[0]) .toEqual({ type: 'text', text: 'X'.repeat(3_000) }) expect(session.snapshotEvents().filter(event => event.type === 'tool/result' && event.surfaceOp !== 'append')).toHaveLength(0) @@ -1135,7 +1137,7 @@ describe('compaction region transaction', () => { compact.mutateDuringSummary = () => { session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'concurrent surface mutation' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: 'append' }) } const nodes = session.surface.nodes @@ -1275,7 +1277,12 @@ describe('default one-shot summarizer', () => { expect(adapter.lastOptions).not.toHaveProperty('system') expect(adapter.lastOptions?.tools).toEqual(tools) expect(adapter.lastOptions?.messages.slice(0, -1)).toEqual(prefix) - expect(adapter.lastOptions?.messages.at(-1)).toMatchObject({ role: 'user' }) + const instruction = adapter.lastOptions?.messages.at(-1) + expect(instruction).toMatchObject({ role: 'user' }) + expect(instruction).not.toHaveProperty('id') + expect(instruction).not.toHaveProperty('source') + expect(Object.isFrozen(instruction)).toBe(true) + expect(Object.isFrozen(instruction?.content[0])).toBe(true) expect(result.shadowedSeqs).toEqual(nodes.slice(start, start + 2)) if (system !== undefined) expect(session.surface.nodes[0]).toBe(nodes[0]) }) @@ -1346,9 +1353,9 @@ describe('default one-shot summarizer', () => { }, }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) - const system = createSystemMessage('REPLAYED SYSTEM', SYSTEM_PROMPT_PLUGIN) + const system = createSystemMessage('REPLAYED SYSTEM') await compact.runSummarize({ tools, messages: [system, prefix], @@ -1386,10 +1393,10 @@ describe('default one-shot summarizer', () => { ctx.llm.registerAdapter(['policy-summary'], policyAdapter) const prefix: Message = createUserMessage({ content: [{ type: 'text', text: 'warm prefix' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) - const system = createSystemMessage('WARM SYSTEM', SYSTEM_PROMPT_PLUGIN) + const system = createSystemMessage('WARM SYSTEM') const output = await compact.runSummarize({ messages: [system, prefix], }, agent(conversation(1), 'fallback')) @@ -1525,20 +1532,16 @@ describe('default one-shot summarizer', () => { .rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) }) - it('rejects image summary output nested in a tool result', async () => { + it('rejects image summary output', async () => { const { compact } = await summarizerHarness([{ - type: 'tool-result', - toolCallId: ToolCallId('summary-tool'), - content: [{ - type: 'image', - attachment: { - attachmentId: AttachmentId(`sha256:${'c'.repeat(64)}`), - mediaType: 'image/png', - bytes: 1, - width: 1, - height: 1, - }, - }], + type: 'image', + attachment: { + attachmentId: AttachmentId(`sha256:${'c'.repeat(64)}`), + mediaType: 'image/png', + bytes: 1, + width: 1, + height: 1, + }, }]) await expect(compact.runSummarize(promptInput('history'), agent(conversation(1), MODEL))) .rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) @@ -2098,7 +2101,7 @@ describe('route-priced image pressure', () => { }] const framed = ctx.tokenMeter.estimateMessage(createUserMessage({ content: frameSummary(compact.summary), - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) expect(framed).toBeGreaterThan(imageNode.heuristicTokens) expect(framed).toBeLessThan(imageNode.tokens) diff --git a/packages/compaction/compaction-basic/tests/compaction-loop-repro.spec.ts b/packages/compaction/compaction-basic/tests/compaction-loop-repro.spec.ts index a527226c03..decedf019e 100644 --- a/packages/compaction/compaction-basic/tests/compaction-loop-repro.spec.ts +++ b/packages/compaction/compaction-basic/tests/compaction-loop-repro.spec.ts @@ -336,7 +336,7 @@ describe('token pressure after loop-admitted system prompts', () => { agent.session.append('system/message', { turn, step, - message: createSystemMessage('retry guidance', '@deepseek-ai/dsh-system-prompt'), + message: createSystemMessage('retry guidance'), }, { surfaceOp: { op: 'replace', startSeq: node, endSeq: node }, sourceEventSeqs: [node] }) return { kind: 'retry' } }) diff --git a/packages/compaction/compaction-basic/tests/manual-compaction.spec.ts b/packages/compaction/compaction-basic/tests/manual-compaction.spec.ts index 26d957ce92..744416e219 100644 --- a/packages/compaction/compaction-basic/tests/manual-compaction.spec.ts +++ b/packages/compaction/compaction-basic/tests/manual-compaction.spec.ts @@ -21,12 +21,14 @@ import type { ContentBlock, LlmResolvedModelInfo, Message, + RequestMessage, StreamChunk, TokenUsage, } from '@deepseek-ai/dsh-llm' -import SessionStore, { Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' +import SessionStore, { buildForkSeed, Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import LlmRuntime from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import TokenMeter from '@deepseek-ai/dsh-token-meter' import type { Agent } from '@deepseek-ai/dsh-agent' import type { @@ -34,6 +36,14 @@ import type { SummaryResult, } from '@deepseek-ai/dsh-compaction-basic/src/summarizer.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'listener': { kind: 'listener' } & ContextFormed + 'rival': { kind: 'rival' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + } +} + const MODEL = 'mock' const SIGNAL = new AbortController().signal const PROMPT = 'older conversation history '.repeat(60) @@ -69,7 +79,7 @@ class GatedCompactionEngine extends BasicCompactionEngine { /** One text answer per request, with a context window large enough to avoid pressure. */ class TextAdapter extends LlmAdapter { - readonly requests: Message[][] = [] + readonly requests: RequestMessage[][] = [] override resolveModel(provider: string, model: string): Promise { return Promise.resolve({ @@ -80,7 +90,7 @@ class TextAdapter extends LlmAdapter { }) } - override async * stream(options: { messages: readonly Message[] }): AsyncIterable { + override async * stream(options: { messages: readonly RequestMessage[] }): AsyncIterable { this.requests.push([...options.messages]) yield { type: 'block-start', index: 0, blockType: 'text' } yield { type: 'block-end', index: 0, block: { type: 'text', text: 'answer' } } @@ -312,7 +322,7 @@ describe('compactNow through the real loop', () => { compact.duringSummary = () => { agent.inject(createUserMessage({ content: [{ type: 'text', text: 'INJECTED CONTEXT' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) } @@ -321,7 +331,7 @@ describe('compactNow through the real loop', () => { expect(result).not.toBeNull() const start = agent.session.snapshotEvents().findLast(event => event.type === 'compaction/start') const injected = agent.inbox.nextStep.find(message => - message.source.kind === 'plugin' && message.source.plugin === 'test') + message.source.kind === 'test') const end = agent.session.snapshotEvents().findLast(event => event.type === 'compaction/end') expect(start).toBeDefined() expect(injected).toBeDefined() @@ -350,7 +360,7 @@ describe('compactNow through the real loop', () => { attempts.push(event.type) agent.inject(createUserMessage({ content: [{ type: 'text', text: `from ${event.type}` }], - source: { kind: 'plugin', plugin: 'listener' }, + source: { kind: 'listener' }, })) }) @@ -361,7 +371,7 @@ describe('compactNow through the real loop', () => { expect(agent.session.deriveMessages()[0]?.role).toBe('system') expect(derivedText(agent.session)[1]).toContain('checkpoint') expect(agent.session.snapshotEvents().filter(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' && event.data.source.plugin === 'listener')).toHaveLength(0) + && event.data.source.kind === 'listener')).toHaveLength(0) const types = compactEvents(agent.session).map(event => event.type) expect(types).toEqual(['compaction/start', 'compaction/summary', 'compaction/end']) }) @@ -477,6 +487,28 @@ describe('compactNow transaction and failure classification', () => { expect(compact.calls).toHaveLength(1) }) + it('ignores an unmatched bracket a mid-turn fork seed cut open', async () => { + // A fork boundary inside the source's live compaction bracket: the seed + // keeps the unmatched compaction/start and balances only the turn with + // forked closers — never a synthetic compaction/end. The child's end-seed + // marker proves the inherited lock stale, so compaction is not blocked. + const { compact } = detachedService() + const original = closedConversation(2) + original.append('turn/start', { turn: 3 }) + original.append('compaction/start', { + compactionId: CompactionId('forked-manual-compaction'), + turn: 3, + }) + const seed = buildForkSeed(original.snapshotEvents(), original.snapshotEvents().at(-1)!.seq) + expect(seed.filter(event => event.type === 'compaction/end')).toEqual([]) + expect(seed.at(-1)).toMatchObject({ type: 'turn/end', data: { reason: { kind: 'forked' } } }) + const child = Session.create(SessionId('forked-orphan'), seed) + const agent = fakeAgent(child, () => () => undefined) + + await expect(compact.compactNow(agent, SIGNAL)).resolves.not.toBeNull() + expect(compact.calls).toHaveLength(1) + }) + it('scans a stale orphan independently of later repaired turn state', async () => { const { compact } = detachedService() const original = closedConversation(2) @@ -521,7 +553,7 @@ describe('compactNow transaction and failure classification', () => { const [head] = session.surface.nodes session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'competing replacement' }], - source: { kind: 'plugin', plugin: 'rival' }, + source: { kind: 'rival' }, }), { surfaceOp: { op: 'replace', startSeq: head!, endSeq: head! }, sourceEventSeqs: [head!], @@ -542,7 +574,7 @@ describe('compactNow transaction and failure classification', () => { const middle = session.surface.nodes[1] session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'rewritten middle node' }], - source: { kind: 'plugin', plugin: 'rival' }, + source: { kind: 'rival' }, }), { surfaceOp: { op: 'replace', startSeq: middle!, endSeq: middle! }, sourceEventSeqs: [middle!], @@ -573,7 +605,7 @@ describe('compactNow transaction and failure classification', () => { queueMicrotask(() => { session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'late competing replacement' }], - source: { kind: 'plugin', plugin: 'rival' }, + source: { kind: 'rival' }, }), { surfaceOp: { op: 'replace', startSeq: head, endSeq: head }, sourceEventSeqs: [head], diff --git a/packages/compaction/compaction-image-offload/src/image-offload.ts b/packages/compaction/compaction-image-offload/src/image-offload.ts index 5c686ba4c8..cc8dbfeae0 100644 --- a/packages/compaction/compaction-image-offload/src/image-offload.ts +++ b/packages/compaction/compaction-image-offload/src/image-offload.ts @@ -34,8 +34,6 @@ export function offloadOldestImages(session: Session, sourceEventSeqs: readonly count -= 1 } imageIndex += 1 - } else if (block.type === 'tool-result') { - visit(block.content) } } } diff --git a/packages/compaction/compaction-image-offload/src/project-message.ts b/packages/compaction/compaction-image-offload/src/project-message.ts index 8d5754e2ee..17116ffbfe 100644 --- a/packages/compaction/compaction-image-offload/src/project-message.ts +++ b/packages/compaction/compaction-image-offload/src/project-message.ts @@ -24,9 +24,6 @@ export function offloadMessageImages(message: Message, indexes: readonly number[ selected += 1 } imageIndex += 1 - } else if (block.type === 'tool-result') { - const content = visit(block.content) - if (content !== block.content) projected = { ...block, content } } if (projected !== block) next ??= blocks.slice(0, index) next?.push(projected) diff --git a/packages/compaction/compaction-image-offload/tests/image-offload.spec.ts b/packages/compaction/compaction-image-offload/tests/image-offload.spec.ts index 59ecd36568..2123638197 100644 --- a/packages/compaction/compaction-image-offload/tests/image-offload.spec.ts +++ b/packages/compaction/compaction-image-offload/tests/image-offload.spec.ts @@ -87,13 +87,11 @@ function image(name: string): Extract { function offloadedNames(options: GenerateOptions): string[] { const names: string[] = [] - const visit = (blocks: readonly ContentBlock[]): void => { - for (const block of blocks) { + for (const message of options.messages) { + for (const block of message.content) { if (block.type === 'image' && block.offloaded === true) names.push(block.attachment.name ?? '') - if (block.type === 'tool-result') visit(block.content) } } - for (const message of options.messages) visit(message.content) return names } @@ -235,7 +233,7 @@ describe('compaction-image-offload', () => { }) agent.followup(createUserMessage({ - content: [image('a'), { type: 'tool-result', toolCallId: ToolCallId('shot'), content: [image('b')] }, image('c')], + content: [image('a'), image('b'), image('c')], source: { kind: 'user' }, })) await agent.whenIdle() @@ -297,32 +295,54 @@ describe('compaction-image-offload', () => { ]]) }) - it('offloads a nested tool-result occurrence and leaves later images untouched', async () => { + it('offloads a tool-result image and leaves later images untouched', async () => { const adapter = new ScriptedAdapter([offloadRequired(1), textResponse('sent')]) const ctx = await harness(adapter) const agent = await ctx.agentLoop.create(SessionId('offload-tool-result'), { provider: 'mock', model: 'mock' }) + const emptyCallId = ToolCallId('empty') const callId = ToolCallId('shot') + const innerCallId = ToolCallId('inner') agent.session.append('turn/start', { turn: 0 }) agent.session.append('assistant/message', { turn: 0, step: 1, message: createAssistantMessage({ - content: [{ type: 'tool-call', id: callId, name: 'read_image', arguments: '{}' }], + content: [ + { type: 'tool-call', id: emptyCallId, name: 'read_image', arguments: '{}' }, + { type: 'tool-call', id: callId, name: 'read_image', arguments: '{}' }, + { type: 'tool-call', id: innerCallId, name: 'read_image', arguments: '{}' }, + ], source: { provider: 'mock', model: 'mock' }, }), stream: [], }, { surfaceOp: 'append' }) + agent.session.append('tool/call', { turn: 0, step: 1, callId: emptyCallId, name: 'read_image', arguments: '{}' }) + agent.session.append('tool/result', { + turn: 0, + step: 1, + message: createToolResultMessage({ + callId: emptyCallId, + content: [{ type: 'text', text: 'no image' }], + isError: false, + }), + }, { surfaceOp: 'append' }) agent.session.append('tool/call', { turn: 0, step: 1, callId, name: 'read_image', arguments: '{}' }) const result = agent.session.append('tool/result', { turn: 0, step: 1, message: createToolResultMessage({ callId, - content: [ - { type: 'tool-result', toolCallId: ToolCallId('empty'), content: [{ type: 'text', text: 'no image' }] }, - image('first'), - { type: 'tool-result', toolCallId: ToolCallId('inner'), content: [image('second')] }, - ], + content: [image('first')], + isError: false, + }), + }, { surfaceOp: 'append' }) + agent.session.append('tool/call', { turn: 0, step: 1, callId: innerCallId, name: 'read_image', arguments: '{}' }) + agent.session.append('tool/result', { + turn: 0, + step: 1, + message: createToolResultMessage({ + callId: innerCallId, + content: [image('second')], isError: false, }), }, { surfaceOp: 'append' }) diff --git a/packages/compaction/compaction-image-offload/tests/projection.spec.ts b/packages/compaction/compaction-image-offload/tests/projection.spec.ts index 36d0ec00df..0c82575dab 100644 --- a/packages/compaction/compaction-image-offload/tests/projection.spec.ts +++ b/packages/compaction/compaction-image-offload/tests/projection.spec.ts @@ -21,13 +21,11 @@ function input(session: Session, content: ContentBlock[] = [image, image]) { function marked(session: Session): boolean[] { const result: boolean[] = [] - const visit = (content: readonly ContentBlock[]): void => { - for (const block of content) { + for (const message of session.deriveMessages()) { + for (const block of message.content) { if (block.type === 'image') result.push(block.offloaded === true) - if (block.type === 'tool-result') visit(block.content) } } - for (const message of session.deriveMessages()) visit(message.content) return result } @@ -36,8 +34,8 @@ describe('durable image selections', () => { const session = createSession(SessionId('images')) const source = input(session, [ { type: 'text', text: 'before' }, image, - { type: 'tool-result', toolCallId: ToolCallId('nested'), content: [image, { type: 'text', text: 'after' }] }, - { type: 'tool-result', toolCallId: ToolCallId('text'), content: [{ type: 'text', text: 'unchanged' }] }, + image, { type: 'text', text: 'after' }, + { type: 'text', text: 'unchanged' }, image, ]) const before = session.deriveMessages() diff --git a/packages/compaction/compaction-tool-result-pruner/src/index.ts b/packages/compaction/compaction-tool-result-pruner/src/index.ts index 333f560d75..5f536bfc9b 100644 --- a/packages/compaction/compaction-tool-result-pruner/src/index.ts +++ b/packages/compaction/compaction-tool-result-pruner/src/index.ts @@ -146,17 +146,13 @@ export class ToolResultPruner extends Service { let charsRemoved = 0 for (const { seq, event } of candidates) { const original = session.deriveEventMessage(event) as ToolResultMessage - const result = original.content[0] - const content = this.pruneContent(result.content) + const content = this.pruneContent(original.content) if (content === null) continue - const charsBefore = this.measureContent(result.content) + const charsBefore = this.measureContent(original.content) const charsAfter = this.measureContent(content) const message = freezeMessage({ ...original, - content: [{ - ...result, - content, - }] as [typeof result], + content, }) // Shadow-price protocol: the metering event and its replacement are // appended synchronously adjacent, so pure consumers subtract the diff --git a/packages/compaction/compaction-tool-result-pruner/tests/tool-result-pruner.spec.ts b/packages/compaction/compaction-tool-result-pruner/tests/tool-result-pruner.spec.ts index dc94a7c682..d7bbbae5c9 100644 --- a/packages/compaction/compaction-tool-result-pruner/tests/tool-result-pruner.spec.ts +++ b/packages/compaction/compaction-tool-result-pruner/tests/tool-result-pruner.spec.ts @@ -212,10 +212,7 @@ describe('ToolResultPruner session transaction', () => { type: 'tool/result', data: { message: { - content: [{ - type: 'tool-result', - content: [{ type: 'text', text: 'x'.repeat(100) }], - }], + content: [{ type: 'text', text: 'x'.repeat(100) }], }, }, }) @@ -227,7 +224,9 @@ describe('ToolResultPruner session transaction', () => { isError: true, message: { source: { kind: 'tool', callId: ToolCallId('one') }, - content: [{ type: 'tool-result', isError: true }], + role: 'tool', + toolCallId: ToolCallId('one'), + isError: true, }, error: { name: 'ExitError', code: 'EXIT_1' }, meta: { diff: ['a', 'b'] }, diff --git a/packages/compaction/compaction/src/checkpoint.ts b/packages/compaction/compaction/src/checkpoint.ts index 395a70c1f6..5cba6ca14c 100644 --- a/packages/compaction/compaction/src/checkpoint.ts +++ b/packages/compaction/compaction/src/checkpoint.ts @@ -16,7 +16,7 @@ import type { MessageSource } from '@deepseek-ai/dsh-llm/message' import type { CommandId } from '@deepseek-ai/dsh-commands/brand' import type { CompactionId } from './brand.ts' -const COMPACT_CHECKPOINT_MARKER = Object.freeze({ kind: 'plugin', plugin: 'compact' } as const) +const COMPACT_CHECKPOINT_MARKER = Object.freeze({ kind: 'compact-checkpoint' } as const) /** Message source carried by a concrete compaction checkpoint. */ export type CompactionCheckpointSource = typeof COMPACT_CHECKPOINT_MARKER & { @@ -46,6 +46,6 @@ export function compactCheckpointSource( * @param source - source restored from a surface user message. * @returns whether the source carries the backend-independent checkpoint marker. */ -export function isCompactCheckpointSource(source: MessageSource): boolean { - return source.kind === 'plugin' && source.plugin === COMPACT_CHECKPOINT_MARKER.plugin +export function isCompactCheckpointSource(source: MessageSource): source is CompactionCheckpointSource { + return source.kind === 'compact-checkpoint' } diff --git a/packages/compaction/compaction/src/index.ts b/packages/compaction/compaction/src/index.ts index eb8263f200..3efe4e87eb 100644 --- a/packages/compaction/compaction/src/index.ts +++ b/packages/compaction/compaction/src/index.ts @@ -11,6 +11,7 @@ import { Context, Service } from '@deepseek-ai/cordis' import type { Session, SessionSeq } from '@deepseek-ai/dsh-session' import type { CommandId } from '@deepseek-ai/dsh-commands/brand' import type { CompactionResult } from './types.ts' +import type { CompactionCheckpointSource } from './checkpoint.ts' export type { CompactionResult } from './types.ts' export { CompactionId } from './brand.ts' @@ -21,6 +22,12 @@ export { toolPairingBalancedAfter, toolPairingBalancedBefore } from './tool-pair export { compactCheckpointSource, isCompactCheckpointSource } from './checkpoint.ts' export type { CompactionCheckpointSource } from './checkpoint.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'compact-checkpoint': CompactionCheckpointSource + } +} + /** Why automatic policy is asking a backend to consider compaction. */ export type CompactionTrigger = 'pressure' | 'context-overflow' diff --git a/packages/compaction/compaction/src/invariant.ts b/packages/compaction/compaction/src/invariant.ts index 7880e5fb24..0b347a71eb 100644 --- a/packages/compaction/compaction/src/invariant.ts +++ b/packages/compaction/compaction/src/invariant.ts @@ -97,10 +97,9 @@ function validateSourceCommandId( /** Validate one replacement checkpoint against its open compaction transaction. */ function validateCheckpoint( trace: SessionTrace, - event: SessionEvent<'user/message'>, + source: CompactionCheckpointSource, fail: InvariantFailure, ): void { - const source = event.data.source as typeof event.data.source & Partial validateId(source.compactionId, 'compaction checkpoint compactionId', fail) if (source.sourceCommandId !== undefined) { validateId(source.sourceCommandId, 'compaction checkpoint sourceCommandId', fail) @@ -190,7 +189,7 @@ function validateCompactionEvent( if (event.type === 'user/message' && isReplacementSurfaceEvent(event) && isCompactCheckpointSource(event.data.source)) { - validateCheckpoint(trace, event, fail) + validateCheckpoint(trace, event.data.source, fail) return undefined } if (event.type !== 'compaction/start' && event.type !== 'compaction/summary' && event.type !== 'compaction/end') { diff --git a/packages/compaction/compaction/tests/compaction.spec.ts b/packages/compaction/compaction/tests/compaction.spec.ts index 350d4b8308..3178125b1b 100644 --- a/packages/compaction/compaction/tests/compaction.spec.ts +++ b/packages/compaction/compaction/tests/compaction.spec.ts @@ -1,4 +1,5 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { @@ -13,6 +14,12 @@ import type { SessionSeq } from '@deepseek-ai/dsh-session' import type { CompactionAgentContext } from '@deepseek-ai/dsh-compaction' import type { ManualCompactAgentContext } from '@deepseek-ai/dsh-compaction' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'other': { kind: 'other' } & ContextFormed + } +} + /** * A trivial concrete CompactionEngine implementing the abstract contract. The * Service Definition package owns no algorithm — these tests exercise its contract: @@ -146,7 +153,7 @@ describe('CompactionEngine seam', () => { && isCompactCheckpointSource(event.data.source)) expect(checkpoint?.type === 'user/message' && checkpoint.data.source) .toEqual(compactCheckpointSource(result.compactionId)) - expect(isCompactCheckpointSource({ kind: 'plugin', plugin: 'other' })).toBe(false) + expect(isCompactCheckpointSource({ kind: 'other' })).toBe(false) expect(isCompactCheckpointSource({ kind: 'user' })).toBe(false) expect(session.snapshotEvents().filter(e => e.type.startsWith('compaction/')).map(e => e.type)) .toEqual(['compaction/start', 'compaction/summary', 'compaction/end']) diff --git a/packages/compaction/compaction/tests/tool-pairing.spec.ts b/packages/compaction/compaction/tests/tool-pairing.spec.ts index a5694d1514..f47c39a9ee 100644 --- a/packages/compaction/compaction/tests/tool-pairing.spec.ts +++ b/packages/compaction/compaction/tests/tool-pairing.spec.ts @@ -1,9 +1,16 @@ import { describe, expect, it } from 'vitest' import { createUserMessage, ToolCallId , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm' -import { toolPairingBalancedAfter, toolPairingBalancedBefore } from '@deepseek-ai/dsh-compaction' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +import { CompactionId, compactCheckpointSource, toolPairingBalancedAfter, toolPairingBalancedBefore } from '@deepseek-ai/dsh-compaction' import { Session, SessionId, SessionSeq } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionSeq as SessionSeqType } from '@deepseek-ai/dsh-session' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const SURFACE = { surfaceOp: 'append' as const } function seqOf(session: Session, type: SessionEvent['type'], nth = 0): SessionSeqType { @@ -138,7 +145,7 @@ describe('tool-pairing boundaries', () => { }, SURFACE) midStep.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'background update' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), SURFACE) midStep.append('tool/result', { turn: 1, step: 1, @@ -170,7 +177,7 @@ describe('tool-pairing surface identity', () => { const nodes = session.surface.nodes session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'checkpoint' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: compactCheckpointSource(CompactionId('tool-pairing-compaction')), }), { surfaceOp: { op: 'replace', startSeq: nodes[0]!, endSeq: nodes.at(-1)! }, sourceEventSeqs: [...nodes], diff --git a/packages/context/agent-instructions/src/state.ts b/packages/context/agent-instructions/src/state.ts index b7638f86eb..61d8fa4237 100644 --- a/packages/context/agent-instructions/src/state.ts +++ b/packages/context/agent-instructions/src/state.ts @@ -93,7 +93,7 @@ function agentInstructionsHook(text: string, changes: AgentInstructionChange[]): export function agentInstructionsMessage(text: string): Message { return createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: name }, + source: { kind: name, form: 'instructions', changes: [] }, }) } diff --git a/packages/context/agent-instructions/tests/agent-instructions.spec.ts b/packages/context/agent-instructions/tests/agent-instructions.spec.ts index 469132f21e..533b443256 100644 --- a/packages/context/agent-instructions/tests/agent-instructions.spec.ts +++ b/packages/context/agent-instructions/tests/agent-instructions.spec.ts @@ -5,11 +5,12 @@ import { afterAll, describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import Loader from '@deepseek-ai/cordis-plugin-loader' import * as AgentInstructions from '@deepseek-ai/dsh-agent-instructions' -import LlmRuntime, { createUserMessage, ToolCallId, type Message, type StreamChunk } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createUserMessage, ToolCallId, type Message, type MessageSource, type StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, SessionSeq, type SessionEvent, type SurfaceIntent, type UserMessage } from '@deepseek-ai/dsh-session' +import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import AgentRegistry, { agentEvents, type Agent } from '@deepseek-ai/dsh-agent' import AgentLoop, { turnBoundaryProjectionDefinition } from '@deepseek-ai/dsh-agent-loop' -import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { FileSystem, FsTargetKey, FsVersion } from '@deepseek-ai/dsh-fs' import type { FsDirEntry, @@ -48,6 +49,21 @@ import { mountAgentLoopTestHarness, } from '@deepseek-ai/dsh-agent-loop-testkit' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'downstream': { kind: 'downstream' } & ContextFormed + 'other': { kind: 'other' } & ContextFormed + 'test-skills': { kind: 'test-skills' } & ContextFormed + } +} + +type CheckpointSource = Extract + +/** Build a typed checkpoint source for an instruction projection fixture. */ +function checkpointSource(compactionId: string): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: compactionId as CheckpointSource['compactionId'] } +} + /** Per-candidate reconciliation scope key: directory paired with the file name. */ const sk = (directory: string, candidateName: string): string => candidateScopeKey(directory, candidateName) @@ -252,7 +268,7 @@ function stubToolExecution( } } -function blocksText(blocks: { type: string; text?: string }[] | undefined): string { +function blocksText(blocks: readonly { type: string; text?: string }[] | undefined): string { return blocks?.map(block => block.type === 'text' ? block.text ?? '' : '').join('\n') ?? '' } @@ -1747,7 +1763,7 @@ describe('workspace context request injection', () => { agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted summary' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource('instruction-compaction-1'), }), { surfaceOp: { op: 'replace', startSeq: baseline!.seq, endSeq: baseline!.seq }, sourceEventSeqs: [baseline!.seq], @@ -1780,7 +1796,7 @@ describe('workspace context request injection', () => { agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted summary' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource('instruction-compaction-2'), }), { surfaceOp: { op: 'replace', startSeq: baseline!.seq, endSeq: baseline!.seq }, sourceEventSeqs: [baseline!.seq], @@ -1883,7 +1899,7 @@ describe('workspace context request injection', () => { ...decision, messages: [ ...decision.messages, - createUserMessage({ content: [{ type: 'text', text: 'Available skills' }], source: { kind: 'plugin', plugin: 'test-skills' } }), + createUserMessage({ content: [{ type: 'text', text: 'Available skills' }], source: { kind: 'test-skills' } }), ], } }) @@ -3711,7 +3727,7 @@ describe('dynamic nested workspace context injection', () => { agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted summary' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource('instruction-compaction-3'), }), { surfaceOp: { op: 'replace', startSeq: SessionSeq(contextSeq), endSeq: SessionSeq(contextSeq) }, sourceEventSeqs: [SessionSeq(contextSeq)], @@ -3758,7 +3774,7 @@ describe('dynamic nested workspace context injection', () => { }) agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted summary' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource('instruction-compaction-4'), }), { surfaceOp: { op: 'replace', startSeq: baseline!.seq, endSeq: baseline!.seq }, sourceEventSeqs: [baseline!.seq], @@ -3902,7 +3918,7 @@ describe('dynamic nested workspace context injection', () => { }), { surfaceOp: 'append' }) agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'foreign plugin context' }], - source: { kind: 'plugin', plugin: 'other' }, + source: { kind: 'other' }, }), { surfaceOp: 'append' }) await ctx.tools.execute({ @@ -4016,7 +4032,7 @@ describe('dynamic nested workspace context injection', () => { }, additionalContexts: [createUserMessage({ content: [{ type: 'text' as const, text: 'downstream context' }], - source: { kind: 'plugin' as const, plugin: 'downstream' }, + source: { kind: 'downstream' as const }, })], })) @@ -4050,7 +4066,7 @@ describe('dynamic nested workspace context injection', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'downstream context' }], - source: { kind: 'plugin', plugin: 'downstream' }, + source: { kind: 'downstream' }, }) } finally { await rm(root, { recursive: true, force: true }) diff --git a/packages/context/session-reference/src/projection.ts b/packages/context/session-reference/src/projection.ts index 316458c54f..196c75b4e1 100644 --- a/packages/context/session-reference/src/projection.ts +++ b/packages/context/session-reference/src/projection.ts @@ -51,6 +51,7 @@ function projectSessionConversation(snapshot: SessionSurfaceSnapshot): Projected if (text !== '') conversation.push({ role: 'assistant', text, checkpoint: false, originalText: text, omittedBytes: 0 }) break } + case 'developer/message': case 'system/message': case 'tool/result': break diff --git a/packages/context/session-reference/tests/session-reference.spec.ts b/packages/context/session-reference/tests/session-reference.spec.ts index 98da2c861b..6ea0ed8cf2 100644 --- a/packages/context/session-reference/tests/session-reference.spec.ts +++ b/packages/context/session-reference/tests/session-reference.spec.ts @@ -2,7 +2,8 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { agentEvents, installModelSelection, type Agent, type ModelSelectionRef } from '@deepseek-ai/dsh-agent' import { CompactionId, compactCheckpointSource } from '@deepseek-ai/dsh-compaction' -import LlmRuntime, { createMessage, createSystemMessage, createToolResultMessage, createUserMessage, LlmError, ToolCallId } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createDeveloperMessage, createMessage, createSystemMessage, createToolResultMessage, createUserMessage, LlmError, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, SessionSeq } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import SessionQueryEngine from '@deepseek-ai/dsh-session-query' @@ -19,6 +20,13 @@ import SessionReferenceResolver, { import { stringifyTagSafeJson } from '../src/serialization.ts' import { SpillLocator, SpillStore, type SaveTextSpill, type SpillRef } from '@deepseek-ai/dsh-spill' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + 'workspace': { kind: 'workspace' } & ContextFormed + } +} + class TestSessionQueryEngine extends SessionQueryEngine { override searchSessions( ..._args: Parameters @@ -92,7 +100,7 @@ function checkpointSource(id: string) { function appendConversation(session: Session): void { session.append( 'system/message', - { turn: 1, step: 1, message: createSystemMessage('system prompt secret', 'system-prompt') }, + { turn: 1, step: 1, message: createSystemMessage('system prompt secret') }, { surfaceOp: 'append' }, ) const oldUser = session.append( @@ -140,7 +148,7 @@ function appendConversation(session: Session): void { session.append( 'user/message', createUserMessage({ - content: [{ type: 'text', text: 'workspace secret' }], source: { kind: 'plugin', plugin: 'workspace' }, + content: [{ type: 'text', text: 'workspace secret' }], source: { kind: 'workspace' }, }), { surfaceOp: 'append' }, ) @@ -156,7 +164,7 @@ function appendConversation(session: Session): void { 'user/message', createUserMessage({ content: [{ type: 'text', text: 'plugin steer' }], - source: { kind: 'plugin', plugin: 'goal' }, + source: { kind: 'test' }, }), { surfaceOp: 'append' }, ) @@ -192,7 +200,7 @@ function appendConversation(session: Session): void { session.append( 'user/message', createUserMessage({ - content: [{ type: 'text', text: 'plugin-generated user' }], source: { kind: 'plugin', plugin: 'goal' }, + content: [{ type: 'text', text: 'plugin-generated user' }], source: { kind: 'test' }, }), { surfaceOp: 'append' }, ) @@ -863,7 +871,7 @@ describe('session reference discovery and preparation', () => { }) const plugin = createUserMessage({ content: [{ type: 'text', text: formatSessionReferenceMention({ sessionId: source.id, label: 'Ignored' }) }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) const signal = new AbortController().signal @@ -1007,6 +1015,12 @@ describe('session reference discovery and preparation', () => { const ctx = await harness() const target = ctx.sessions.create(SessionId('target')) const source = ctx.sessions.create(SessionId('source')) + source.append('developer/message', { + turn: 1, step: 1, + message: createDeveloperMessage({ + content: [{ type: 'tool-removal', toolName: 'private_tool' }], source: { kind: 'test' }, + }), + }, { surfaceOp: 'append' }) source.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'nested referenced snapshot must not propagate' }], source: { diff --git a/packages/context/time-context/src/index.ts b/packages/context/time-context/src/index.ts index f626342546..8a215b87f7 100644 --- a/packages/context/time-context/src/index.ts +++ b/packages/context/time-context/src/index.ts @@ -10,6 +10,13 @@ import z from '@deepseek-ai/schemastery' import { z as zod } from 'zod' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'time-context': { kind: 'time-context' } & ContextFormed + } +} + import type { UserMessage } from '@deepseek-ai/dsh-llm' import { SessionSeq } from '@deepseek-ai/dsh-session' import type {} from '@deepseek-ai/dsh-session-projection' @@ -160,7 +167,7 @@ export function apply(ctx: Context, config: Config): void { return state.lastTurnInjectionTime === null ? state : { ...state, lastTurnInjectionTime: null } } if (event.type === 'user/message') { - const injected = event.data.source.kind === 'plugin' && event.data.source.plugin === name + const injected = event.data.source.kind === name const withMessage = state.lastMessageTime === event.time ? state : { ...state, lastMessageTime: event.time } @@ -214,7 +221,7 @@ export function apply(ctx: Context, config: Config): void { ...decision.messages, createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: name, form: 'snapshot', sections: [{ name, text }] }, + source: { kind: name, form: 'snapshot', sections: [{ name, text }] }, }), ], } diff --git a/packages/context/time-context/src/invariant.ts b/packages/context/time-context/src/invariant.ts index 2fa686a4f4..e9f362c7e4 100644 --- a/packages/context/time-context/src/invariant.ts +++ b/packages/context/time-context/src/invariant.ts @@ -105,7 +105,7 @@ function validateReading( } const source = event.data.source /* v8 ignore next 2 -- replay and dispatch callers select this exact package-owned source before validation. */ - if (source.kind !== 'plugin' || source.plugin !== SOURCE_NAME) { + if (source.kind !== SOURCE_NAME) { fail('time-context source must retain package ownership') } const sections: unknown = 'sections' in source ? source.sections : undefined @@ -113,7 +113,7 @@ function validateReading( const section = typeof sectionValue === 'object' && sectionValue !== null ? sectionValue as Record : undefined - if (Object.keys(source).length !== 4 + if (Object.keys(source).length !== 3 || source.form !== 'snapshot' || !Array.isArray(sections) || sections.length !== 1 @@ -165,8 +165,7 @@ function validateSession(session: Session, fail: InvariantFailure): void { const events = session.snapshotEvents() for (const [index, event] of events.entries()) { if (event.type !== 'user/message' - || event.data.source.kind !== 'plugin' - || event.data.source.plugin !== SOURCE_NAME) continue + || event.data.source.kind !== SOURCE_NAME) continue validateReading(events.slice(0, index), event, fail) } } @@ -179,8 +178,7 @@ const install: InvariantInstaller = Object.assign((ctx: Context, fail: Invariant if (eventName !== 'session/event') return const [session, event] = args as [Session, SessionEvent] if (event.type !== 'user/message' - || event.data.source.kind !== 'plugin' - || event.data.source.plugin !== SOURCE_NAME) return + || event.data.source.kind !== SOURCE_NAME) return // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred. validateReading(session.snapshotEvents(), event, fail) }, { global: true }) diff --git a/packages/context/time-context/tests/invariant.spec.ts b/packages/context/time-context/tests/invariant.spec.ts index 74ab8b5241..cba6fc48d0 100644 --- a/packages/context/time-context/tests/invariant.spec.ts +++ b/packages/context/time-context/tests/invariant.spec.ts @@ -31,12 +31,11 @@ function event( content: (content ?? [{ type: 'text', text }]) as ContentBlock[], source: plugin === 'time-context' ? { - kind: 'plugin', - plugin, + kind: 'time-context', form: 'snapshot', sections: [{ name: plugin, text }], } - : { kind: 'plugin', plugin }, + : { kind: 'other' }, }), } } @@ -78,8 +77,7 @@ function appendReading(session: Session, text: string): void { session.append('user/message', createUserMessage({ content: [{ type: 'text', text }], source: { - kind: 'plugin', - plugin: 'time-context', + kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text }], }, @@ -287,23 +285,20 @@ describe('time-context invariants', () => { const ctx = await setup() const base = event(reading()) for (const source of [ - { kind: 'plugin', plugin: 'time-context' }, + { kind: 'time-context' }, { ...base.data.source, authority: {} }, { - kind: 'plugin', - plugin: 'time-context', + kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text: 'different' }], }, { - kind: 'plugin', - plugin: 'time-context', + kind: 'time-context', form: 'snapshot', sections: { 0: { name: 'time-context', text: reading() }, length: 1 }, }, { - kind: 'plugin', - plugin: 'time-context', + kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text: reading(), extra: true }], }, diff --git a/packages/context/time-context/tests/request-zone.spec.ts b/packages/context/time-context/tests/request-zone.spec.ts index 5fed54d7cb..a4752eea73 100644 --- a/packages/context/time-context/tests/request-zone.spec.ts +++ b/packages/context/time-context/tests/request-zone.spec.ts @@ -1,11 +1,18 @@ import { describe, expect, it } from 'vitest' import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { UserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { deriveBrowserTimeZoneContext, renderBrowserTimeZoneContext, } from '../src/request-zone.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + function browserMessage(timeZone: string): UserMessage { return createUserMessage({ content: [{ type: 'text', text: timeZone }], @@ -17,7 +24,7 @@ describe('browser request-zone context', () => { it('derives missing, unique, and sorted mixed zones from user-rpc messages only', () => { const plugin = createUserMessage({ content: [{ type: 'text', text: 'plugin' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) expect(deriveBrowserTimeZoneContext([plugin])).toEqual({ kind: 'missing' }) expect(deriveBrowserTimeZoneContext([ diff --git a/packages/context/time-context/tests/time-context.e2e.ts b/packages/context/time-context/tests/time-context.e2e.ts index fbc999af05..1844872db9 100644 --- a/packages/context/time-context/tests/time-context.e2e.ts +++ b/packages/context/time-context/tests/time-context.e2e.ts @@ -50,8 +50,7 @@ describe('time-context through the production headless profile', () => { const contexts = events.filter( (event): event is SessionEvent<'user/message'> => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === 'time-context') + && event.data.source.kind === 'time-context') const starts = events.filter(event => event.type === 'step/start') expect(contexts).toHaveLength(2) expect(starts).toHaveLength(2) @@ -61,8 +60,7 @@ describe('time-context through the production headless profile', () => { // `snapshot` form: one named contribution whose text is exactly what the // model read, so a consumer attributes it without re-splitting prose. expect(contexts[index]!.data.source).toMatchObject({ - kind: 'plugin', - plugin: 'time-context', + kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context' }], }) diff --git a/packages/context/time-context/tests/time-context.spec.ts b/packages/context/time-context/tests/time-context.spec.ts index 52700e6d62..454baf309b 100644 --- a/packages/context/time-context/tests/time-context.spec.ts +++ b/packages/context/time-context/tests/time-context.spec.ts @@ -3,6 +3,7 @@ import { Context } from '@deepseek-ai/cordis' import Loader from '@deepseek-ai/cordis-plugin-loader' import { createUserMessage, ToolCallId, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import AgentRegistry, { agentEvents, type Agent } from '@deepseek-ai/dsh-agent' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' @@ -12,6 +13,13 @@ import { unsupportedInbox, mountAgentLoopTestDependencies } from '@deepseek-ai/d import * as timeContext from '@deepseek-ai/dsh-time-context' import type { Config } from '@deepseek-ai/dsh-time-context' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'compaction-basic': { kind: 'compaction-basic' } & ContextFormed + 'time-context-test': { kind: 'time-context-test' } & ContextFormed + } +} + const BASE = Date.parse('2026-07-14T00:00:00.000Z') const ORIGINAL_TIME_ZONE = process.env['TZ'] const SIGNAL = new AbortController().signal @@ -70,8 +78,7 @@ function contextTexts(session: Session): string[] { const texts: string[] = [] for (const event of session.snapshotEvents()) { if (event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === 'time-context') { + && event.data.source.kind === 'time-context') { texts.push(event.data.content.find(block => block.type === 'text')?.text ?? '') } } @@ -87,7 +94,7 @@ async function fire( ): Promise { const proposed = createUserMessage({ content: [{ type: 'text', text: 'request proposal' }], - source: { kind: 'plugin', plugin: 'time-context-test' }, + source: { kind: 'time-context-test' }, }) const decision = await agentEvents(ctx, agent).waterfall( 'agent/pre-step', @@ -175,8 +182,7 @@ describe('durable step context', () => { // text is exactly what the model read, so a consumer attributes it without // re-splitting prose. expect(event.data.source).toEqual({ - kind: 'plugin', - plugin: 'time-context', + kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', @@ -292,11 +298,11 @@ describe('durable step context', () => { openMessageTurn(original, 1) await fire(ctx, sessionAgent(original), 1, 1) const user = original.snapshotEvents().find(event => event.type === 'user/message' && event.data.source.kind === 'user') - const reading = original.snapshotEvents().find(event => event.type === 'user/message' && event.data.source.kind === 'plugin') + const reading = original.snapshotEvents().find(event => event.type === 'user/message' && event.data.source.kind === 'time-context') if (user === undefined || reading === undefined) throw new Error('missing source surface events') original.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted history' }], - source: { kind: 'plugin', plugin: 'compaction-basic' }, + source: { kind: 'compaction-basic' }, }), { surfaceOp: { op: 'replace', startSeq: user.seq, endSeq: reading.seq }, sourceEventSeqs: [user.seq, reading.seq], @@ -421,7 +427,7 @@ describe('time-context projection fold edges', () => { session.append('turn/start', { turn: 1 }) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'reading' }], - source: { kind: 'plugin', plugin: 'time-context' }, + source: { kind: 'time-context' }, }), { surfaceOp: 'append' }) expect(typeof ctx.sessionProjections.stateOf(session, 'timeContext')?.lastTurnInjectionTime).toBe('number') session.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) @@ -483,15 +489,14 @@ describe('real agent-loop request history', () => { expect(adapter.requests).toHaveLength(2) const contexts = agent.session.snapshotEvents().filter( - (event): event is SessionEvent<'user/message'> => event.type === 'user/message' && event.data.source.kind === 'plugin') + (event): event is SessionEvent<'user/message'> => event.type === 'user/message' && event.data.source.kind !== 'user') const starts = agent.session.snapshotEvents().filter(event => event.type === 'step/start') expect(contexts).toHaveLength(adapter.requests.length) expect(starts).toHaveLength(adapter.requests.length) for (let index = 0; index < contexts.length; index += 1) { expect(contexts[index]!.seq).toBeGreaterThan(starts[index]!.seq) } - expect(contexts.every(event => event.data.source.kind === 'plugin' - && event.data.source.plugin === 'time-context' + expect(contexts.every(event => event.data.source.kind === 'time-context' && event.surfaceOp === 'append')).toBe(true) const firstRequestText = requestText(adapter.requests[0]!) diff --git a/packages/context/tmux-context/src/index.ts b/packages/context/tmux-context/src/index.ts index bfcec10247..42cee71277 100644 --- a/packages/context/tmux-context/src/index.ts +++ b/packages/context/tmux-context/src/index.ts @@ -25,6 +25,17 @@ import type { PreStepDecision } from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-session-projection' import type { ShellExecutor, ShellRunResult } from '@deepseek-ai/dsh-shell' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + /** Location attribution; readers preserve the content without this producer. + * Its projection uses the kind to avoid repeated injection. + * @persistenceAttribution + */ + 'tmux-context': { kind: 'tmux-context' } & ContextFormed + } +} + /** Cordis plugin name used by loader diagnostics. */ export const name = 'tmux-context' @@ -223,8 +234,7 @@ export function apply(ctx: Context, config: Config): void { init: () => null, apply: (state, event) => { if (event.type !== 'user/message' - || event.data.source.kind !== 'plugin' - || event.data.source.plugin !== name) return state + || event.data.source.kind !== name) return state const [block] = event.data.content if (block?.type !== 'text') return state const newline = block.text.indexOf('\n') @@ -256,7 +266,7 @@ export function apply(ctx: Context, config: Config): void { messages: [ createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: name, form: 'snapshot', sections: [{ name, text }] }, + source: { kind: name, form: 'snapshot', sections: [{ name, text }] }, }), ...decision.messages, ], diff --git a/packages/context/tmux-context/tests/tmux-context.spec.ts b/packages/context/tmux-context/tests/tmux-context.spec.ts index 535cf596ed..28d7b1027d 100644 --- a/packages/context/tmux-context/tests/tmux-context.spec.ts +++ b/packages/context/tmux-context/tests/tmux-context.spec.ts @@ -125,8 +125,7 @@ function contextTexts(session: Session): string[] { const texts: string[] = [] for (const event of session.snapshotEvents()) { if (event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === 'tmux-context') { + && event.data.source.kind === 'tmux-context') { texts.push(event.data.content.find(block => block.type === 'text')?.text ?? '') } } @@ -176,8 +175,7 @@ describe('tmux-context injection', () => { // `snapshot` form: one named contribution carrying exactly the reading the // model saw, so a consumer attributes it without re-splitting prose. expect(event.data.source).toMatchObject({ - kind: 'plugin', - plugin: 'tmux-context', + kind: 'tmux-context', form: 'snapshot', sections: [{ name: 'tmux-context' }], }) @@ -275,7 +273,7 @@ describe('tmux-context prior-reading resilience', () => { openMessageTurn(session, 1) session.append('user/message', createUserMessage({ content: [{ type: 'reasoning', text: 'not a location' }], - source: { kind: 'plugin', plugin: 'tmux-context' }, + source: { kind: 'tmux-context' }, }), { surfaceOp: 'append' }) await fire(ctx, agent, 1, 1) @@ -291,7 +289,7 @@ describe('tmux-context prior-reading resilience', () => { openMessageTurn(session, 1) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'single line, no newline' }], - source: { kind: 'plugin', plugin: 'tmux-context' }, + source: { kind: 'tmux-context' }, }), { surfaceOp: 'append' }) await fire(ctx, agent, 1, 1) diff --git a/packages/core/agent-loop/src/index.ts b/packages/core/agent-loop/src/index.ts index d39a26a6e9..2f15f60bf0 100644 --- a/packages/core/agent-loop/src/index.ts +++ b/packages/core/agent-loop/src/index.ts @@ -34,6 +34,7 @@ import type { SessionHandle, SessionPersistence } from '@deepseek-ai/dsh-session import { ReactLoopAgent } from './agent.ts' import { inboxProjectionDefinition } from './inbox.ts' import { DEFAULT_MAX_PARALLEL_TOOL_CALLS } from './constants.ts' +import type {} from './runtime-context.ts' /** Fiber states that cannot own or serve a new lifecycle. */ const INACTIVE_STATES: ReadonlySet = new Set([ diff --git a/packages/core/agent-loop/src/runtime-context.ts b/packages/core/agent-loop/src/runtime-context.ts index af9f3fa640..828d377edd 100644 --- a/packages/core/agent-loop/src/runtime-context.ts +++ b/packages/core/agent-loop/src/runtime-context.ts @@ -6,16 +6,21 @@ */ import { createSystemMessage, createUserMessage } from '@deepseek-ai/dsh-llm' -import type { ContextSnapshotSection, Message } from '@deepseek-ai/dsh-llm' +import type { ContextFormed, ContextSnapshotSection, Message } from '@deepseek-ai/dsh-llm' import type { Session, SessionEvent, SessionSeq, SurfaceIntent, SystemMessage, UserMessage } from '@deepseek-ai/dsh-session' import { isReplacementSurfaceEvent } from '@deepseek-ai/dsh-session' import type { Context } from '@deepseek-ai/cordis' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'runtime-context': { kind: 'runtime-context' } & ContextFormed + } +} -const SOURCE = '@deepseek-ai/dsh-system-prompt' +const SOURCE = 'runtime-context' const CLEARED = 'Current runtime context: none. Earlier runtime-context snapshots no longer apply.' function isOwned(message: UserMessage): boolean { - return message.source.kind === 'plugin' && message.source.plugin === SOURCE + return message.source.kind === SOURCE } function textOf(message: Message): string | undefined { @@ -84,7 +89,7 @@ export class SystemPromptProjection { const nodes = this.systemNodes() const head = nodes[0] if (head === undefined) { - return [{ message: createSystemMessage(rendered, SOURCE), intent: { surfaceOp: 'append' } }] + return [{ message: createSystemMessage(rendered), intent: { surfaceOp: 'append' } }] } const latest = nodes.findLast(node => node.text !== '') ?? head if (!input.inHistory || input.startsSeries || rendered.length === 0) { @@ -94,12 +99,12 @@ export class SystemPromptProjection { return updates } if (latest.text === rendered) return [] - return [{ message: createSystemMessage(rendered, SOURCE), intent: { surfaceOp: 'append' } }] + return [{ message: createSystemMessage(rendered), intent: { surfaceOp: 'append' } }] } private replace(seq: SessionSeq, text: string): SystemPromptCommit { return { - message: createSystemMessage(text, SOURCE), + message: createSystemMessage(text), intent: { surfaceOp: { op: 'replace', startSeq: seq, endSeq: seq }, sourceEventSeqs: [seq] }, } } @@ -152,8 +157,8 @@ export class RuntimeContextProjection { content: [{ type: 'text', text: snapshot }], // The cleared marker has no contributions left to attribute. source: sections.length === 0 - ? { kind: 'plugin', plugin: SOURCE } - : { kind: 'plugin', plugin: SOURCE, form: 'snapshot', sections }, + ? { kind: SOURCE } + : { kind: SOURCE, form: 'snapshot', sections }, }) } } diff --git a/packages/core/agent-loop/tests/agent.spec.ts b/packages/core/agent-loop/tests/agent.spec.ts index 2ec5bcf01c..180edf291d 100644 --- a/packages/core/agent-loop/tests/agent.spec.ts +++ b/packages/core/agent-loop/tests/agent.spec.ts @@ -5,11 +5,20 @@ import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import LlmRuntime from '@deepseek-ai/dsh-llm' +import type { MessageSource } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime from '@deepseek-ai/dsh-tools' import { MockAdapter, textResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'p': { kind: 'p' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + } +} + async function harness(adapter: MockAdapter): Promise { const ctx = new Context() await ctx.plugin(LlmRuntime) @@ -33,7 +42,7 @@ describe('Agent', () => { const ctx = await harness(adapter) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'context' }], source: { kind: 'plugin', plugin: 'p' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'context' }], source: { kind: 'p' } })) expect(agent.session.snapshotEvents().map(event => event.type)).toEqual(['agent/inbox/spliced']) expect(agent.status).toBe('idle') @@ -41,15 +50,16 @@ describe('Agent', () => { await agent.whenIdle() }) - it('inject() preserves an explicitly empty plugin source', async () => { + it('inject() preserves an unknown producer source', async () => { const ctx = await harness(new MockAdapter([textResponse('ok')])) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'empty plugin source' }], source: { kind: 'plugin', plugin: '' } })) + const source = { kind: 'unknown-producer' } as unknown as MessageSource + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'empty plugin source' }], source })) const injected = agent.session.snapshotEvents().at(-1) expect(injected?.type === 'agent/inbox/spliced' && injected.data.inserted[0]?.source) - .toEqual({ kind: 'plugin', plugin: '' }) + .toEqual({ kind: 'unknown-producer' }) }) it('emits exact inserted, claimed, and discarded inbox messages', async () => { @@ -76,7 +86,7 @@ describe('Agent', () => { }) const context = createUserMessage({ content: [{ type: 'text', text: 'discard me' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) agent.inject(context) agent.inbox.remove(context.id) @@ -95,7 +105,7 @@ describe('Agent', () => { const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) expect(() => { - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'x', bad: 1n } as never], source: { kind: 'plugin', plugin: 'p' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'x', bad: 1n } as never], source: { kind: 'p' } })) }).toThrow(/non-JSON-serializable/) expect(agent.session.snapshotEvents()).toHaveLength(0) }) @@ -105,7 +115,7 @@ describe('Agent', () => { const ctx = await harness(adapter) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) - agent.steer(createUserMessage({ content: [{ type: 'text', text: 'steer idle' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.steer(createUserMessage({ content: [{ type: 'text', text: 'steer idle' }], source: { kind: 'test' } })) await agent.whenIdle() expect(agent.session.snapshotEvents().some(event => event.type === 'user/message')).toBe(true) diff --git a/packages/core/agent-loop/tests/cancel.spec.ts b/packages/core/agent-loop/tests/cancel.spec.ts index 2b1781083c..872e983639 100644 --- a/packages/core/agent-loop/tests/cancel.spec.ts +++ b/packages/core/agent-loop/tests/cancel.spec.ts @@ -441,17 +441,17 @@ describe('Agent.cancel()', () => { expect(call?.type === 'tool/call' ? call.data.callId : undefined).toBe('c1') expect(result?.type === 'tool/result' ? result.data : undefined).toMatchObject({ message: { + role: 'tool', source: { kind: 'tool', callId: 'c1' }, - content: [{ type: 'tool-result', toolCallId: 'c1', isError: true }], + content: [{ type: 'text' }], + isError: true, }, error: { name: 'AbortError', code: TOOL_ABORTED_BEFORE_DISPATCH }, }) send(agent, 'continue safely') await waitForIdle(ctx, agent) - const replayedResult = adapter.requests[1]!.messages - .flatMap(message => message.content) - .find(block => block.type === 'tool-result') + const replayedResult = adapter.requests[1]!.messages.find(message => message.role === 'tool') expect(replayedResult).toMatchObject({ toolCallId: 'c1', isError: true }) expect(reasons).toEqual([ { kind: 'aborted', reason: { kind: 'user' } }, diff --git a/packages/core/agent-loop/tests/config-session-id.spec.ts b/packages/core/agent-loop/tests/config-session-id.spec.ts index 7e4d1a5d3a..4ca1264f5d 100644 --- a/packages/core/agent-loop/tests/config-session-id.spec.ts +++ b/packages/core/agent-loop/tests/config-session-id.spec.ts @@ -5,6 +5,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import LlmRuntime from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' @@ -17,6 +18,12 @@ import AgentLoop, { CONFIGURED_AGENT_IDENTITIES_KEY } from '@deepseek-ai/dsh-age import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { MockAdapter, textResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const dirs: string[] = [] afterEach(async () => { for (const d of dirs.splice(0)) await rm(d, { recursive: true, force: true }) }) @@ -214,7 +221,7 @@ describe('config-driven session id', () => { cleanupStarted.resolve(undefined) await cleanupGate.promise }) - first.inject(createUserMessage({ content: [{ type: 'text', text: 'persist before cancellation' }], source: { kind: 'plugin', plugin: 'test' } })) + first.inject(createUserMessage({ content: [{ type: 'text', text: 'persist before cancellation' }], source: { kind: 'test' } })) await ctx.sessions.flush(first.session) expect(JSON.stringify(await readStoredEvents(ctx, sessionId))) .toContain('persist before cancellation') diff --git a/packages/core/agent-loop/tests/contract-regressions.spec.ts b/packages/core/agent-loop/tests/contract-regressions.spec.ts index 68cb93f129..c5c606ae54 100644 --- a/packages/core/agent-loop/tests/contract-regressions.spec.ts +++ b/packages/core/agent-loop/tests/contract-regressions.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import LlmRuntime, { createUserMessage, ToolCallId, LlmError, MessageSource, ProviderRequestId, StreamChunk } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { type RequestMessage, createUserMessage, ToolCallId, LlmError, MessageSource, ProviderRequestId, StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionEvent, SessionId, TurnEndReason, type UserMessage } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime, { defineContentToolFixture, type PostToolDecision } from '@deepseek-ai/dsh-tools' @@ -13,6 +14,12 @@ import * as AgentInvariant from '@deepseek-ai/dsh-agent/invariant' import * as AgentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant' import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + async function mountInvariants(ctx: Context): Promise { await ctx.plugin(InvariantRegistry) await ctx.plugin(SessionInvariant) @@ -95,7 +102,7 @@ describe('abort during tool execution ends the turn', () => { description: '', parameters: {}, async execute() { - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'accepted before abort' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'accepted before abort' }], source: { kind: 'test' } })) agent.cancel({ kind: 'user' }) return [{ type: 'text', text: 'done' }] }, @@ -104,7 +111,7 @@ describe('abort during tool execution ends the turn', () => { kind: 'accept', additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'accepted result context after abort' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })) @@ -113,7 +120,7 @@ describe('abort during tool execution ends the turn', () => { expect(agent.session.snapshotEvents() .filter(event => event.type === 'tool/result' - || (event.type === 'user/message' && event.data.source.kind === 'plugin') + || (event.type === 'user/message' && event.data.source.kind !== 'user') || event.type === 'step/end' || event.type === 'turn/end') .map(event => event.type)) .toEqual(['tool/result', 'step/end', 'turn/end']) @@ -125,7 +132,7 @@ describe('abort during tool execution ends the turn', () => { await idle expect(agent.session.snapshotEvents() - .flatMap(event => event.type === 'user/message' && event.data.source.kind === 'plugin' + .flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'user' ? [event.data.content] : [])) .toEqual([ @@ -166,7 +173,7 @@ describe('abort during tool execution ends the turn', () => { kind: 'accept', additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'accepted after first result' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], } }) @@ -177,12 +184,12 @@ describe('abort during tool execution ends the turn', () => { const events = agent.session.snapshotEvents() expect(events .filter(event => event.type === 'tool/result' - || (event.type === 'user/message' && event.data.source.kind === 'plugin') + || (event.type === 'user/message' && event.data.source.kind !== 'user') || event.type === 'step/end' || event.type === 'turn/end') .map(event => event.type)) .toEqual(['tool/result', 'tool/result', 'step/end', 'turn/end']) expect(events.flatMap(event => - event.type === 'user/message' && event.data.source.kind === 'plugin' + event.type === 'user/message' && event.data.source.kind !== 'user' ? [event.data.content] : [])[0]) .toBeUndefined() @@ -220,7 +227,7 @@ describe('abort during tool execution ends the turn', () => { description: '', parameters: {}, async execute(_args, exec) { - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'accepted before disposal' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'accepted before disposal' }], source: { kind: 'test' } })) started.resolve(undefined) const signal = exec.signal if (!signal) throw new Error('tool execution signal is missing') @@ -235,7 +242,7 @@ describe('abort during tool execution ends the turn', () => { kind: 'accept', additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'accepted result context during disposal' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })) @@ -244,7 +251,7 @@ describe('abort during tool execution ends the turn', () => { await fiber.dispose() expect(agent.session.snapshotEvents() - .flatMap(event => event.type === 'user/message' && event.data.source.kind === 'plugin' + .flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'user' ? [event.data.content] : [])) .toEqual([]) @@ -301,7 +308,7 @@ describe('abort during tool execution ends the turn', () => { kind: 'enter' as const, messages: [...decision.messages, createUserMessage({ content: [{ type: 'text', text: 'new turn context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], } } @@ -311,7 +318,7 @@ describe('abort during tool execution ends the turn', () => { await waitForIdle(ctx, agent) expect(agent.session.snapshotEvents().flatMap(event => - event.type === 'user/message' && event.data.source.kind === 'plugin' + event.type === 'user/message' && event.data.source.kind !== 'user' ? [event.data.content] : [])[0]) .toEqual([{ type: 'text', text: 'new turn context' }]) @@ -481,7 +488,7 @@ describe('adapter registration, routing, and accepted-input ownership', () => { description: '', parameters: {}, async execute() { - agent.steer(createUserMessage({ content: [{ type: 'text', text: 's' }], source: { kind: 'plugin', plugin: 'goal' } })) + agent.steer(createUserMessage({ content: [{ type: 'text', text: 's' }], source: { kind: 'goal' } as unknown as MessageSource })) return [] }, })) @@ -503,7 +510,7 @@ describe('adapter registration, routing, and accepted-input ownership', () => { expect(insertedSources).toEqual([ { kind: 'user' }, - { kind: 'plugin', plugin: 'goal' }, + { kind: 'goal' }, ]) expect(insertedShapes).toEqual([ ['content', 'id', 'role', 'source'], @@ -511,8 +518,8 @@ describe('adapter registration, routing, and accepted-input ownership', () => { ]) expect(targets).toEqual(['next-turn', 'next-step']) const steeringSources = agent.session.snapshotEvents().flatMap(e => - e.type === 'user/message' && e.data.source.kind === 'plugin' ? [e.data.source] : []) - expect(steeringSources).toEqual([{ kind: 'plugin', plugin: 'goal' }]) + e.type === 'user/message' && e.data.source.kind !== 'user' ? [e.data.source] : []) + expect(steeringSources).toEqual([{ kind: 'goal' }]) }) it('records each admitted next-step batch before the following claim', async () => { @@ -603,6 +610,152 @@ describe('turn numbering continues across seeded sessions', () => { expect(turns).toEqual([2]) }) + + it('an agent over a mid-turn fork seed continues past the synthetic forked closer as a resume', async () => { + const adapter = new MockAdapter([textResponse('branched reply')]) + const ctx = await harness(adapter) + // A source cut open mid-turn: turn 1 completed under a logged header, turn 2 + // claimed its prompt but never closed. + const source = ctx.sessions.create(SessionId('mid-turn-source')) + source.append('turn/start', { turn: 1 }) + source.append('user/message', createUserMessage({ + content: [{ type: 'text', text: 'first' }], source: { kind: 'user' }, + }), { surfaceOp: 'append' }) + source.append('request/header', { + header: { config: { provider: 'mock', model: 'mock' } }, + reason: 'initial', + }) + source.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) + source.append('turn/start', { turn: 2 }) + source.append('user/message', createUserMessage({ + content: [{ type: 'text', text: 'second' }], source: { kind: 'user' }, + }), { surfaceOp: 'append' }) + const boundary = source.snapshotEvents().at(-1)!.seq + + const child = ctx.sessions.fork(source, boundary, SessionId('mid-turn-child')) + const closer = child.snapshotEvents().at(-1) + expect(closer?.type === 'turn/end' && closer.data.reason).toEqual({ kind: 'forked' }) + + const { agent: forked } = await ctx.agents.create({ + sessionId: SessionId('mid-turn-agent'), seed: child.snapshotEvents(), + inheritedEventCount: child.inheritedEventCount, meta: { isSeeded: true }, + agentOptions: { provider: 'mock', model: 'mock' }, + }) + const turns: number[] = [] + const headerReasons: string[] = [] + ctx.on('session/event', (session, event) => { + if (session !== forked.session) return + if (event.type === 'turn/start') turns.push(event.data.turn) + if (event.type === 'request/header') headerReasons.push(event.data.reason) + }) + forked.followup(createUserMessage({ content: [{ type: 'text', text: 'continue' }], source: { kind: 'user' } })) + await waitForIdle(ctx, forked) + + // The synthetic closer ended turn 2, so the branch's first live turn is 3, + // and its first request over the seeded log is a resume, not a new header. + expect(turns).toEqual([3]) + expect(headerReasons).toEqual(['resume']) + const reply = forked.session.deriveMessages().at(-1) + expect(reply?.role).toBe('assistant') + expect(reply?.content).toEqual([{ type: 'text', text: 'branched reply' }]) + }) +}) + +/** Assert the call/result ordering delivered to the model, including missing results. */ +function expectPairedTools(messages: readonly RequestMessage[]): void { + const pending = new Set() + for (const message of messages) { + if (pending.size > 0) expect(message.role).toBe('tool') + if (message.role === 'tool') { + expect(message.source.kind).toBe('tool') + expect(pending.delete(message.toolCallId)).toBe(true) + continue + } + for (const block of message.content) { + if (block.type === 'tool-call') { + expect(pending.has(block.id)).toBe(false) + pending.add(block.id) + } + } + } + expect([...pending]).toEqual([]) +} + +describe('forked tool history reaches the next model request', () => { + it.each([ + ['assistant/message', 0, 2], + ['tool/call', 0, 2], + ['tool/result', 0, 1], + ['tool/result', 1, 0], + ['step/end', 0, 0], + ] as const)('cuts after %s[%i] and supplies %i missing results', async (type, occurrence, missing) => { + const first = toolCallResponse('call-first', 'first', {}).slice(0, -2) + const second = toolCallResponse('call-second', 'second', {}).map(chunk => ( + 'index' in chunk ? { ...chunk, index: 1 } : chunk + )) + const adapter = new MockAdapter([ + [...first, ...second], textResponse('parent complete'), textResponse('child complete'), + ]) + const ctx = await harness(adapter) + try { + await mountInvariants(ctx) + const executions: string[] = [] + for (const name of ['first', 'second']) { + ctx.tools.register(defineContentToolFixture({ + name, description: '', parameters: {}, + execute: () => { + executions.push(name) + return Promise.resolve([{ type: 'text', text: `${name} result` }]) + }, + })) + } + const parent = await ctx.agentLoop.create(SessionId('paired-parent'), { provider: 'mock', model: 'mock' }) + send(parent, 'run both tools') + await waitForIdle(ctx, parent) + const source = parent.session.snapshotEvents() + const boundary = source.filter(event => event.type === type)[occurrence] + if (boundary === undefined) throw new Error(`parent has no ${type}[${occurrence}]`) + expect(source.at(-1)).toMatchObject({ type: 'turn/end', data: { reason: { kind: 'completed' } } }) + expectPairedTools(adapter.requests[1]!.messages) + + const child = ctx.sessions.fork(parent.session, boundary.seq, SessionId('paired-child')) + expect(child.snapshotEvents().slice(0, boundary.seq + 1)).toEqual(source.slice(0, boundary.seq + 1)) + const closers = child.snapshotEvents().slice(boundary.seq + 1, child.firstLiveSeq) + const results = closers.filter(event => event.type === 'tool/result') + expect(results).toHaveLength(missing) + expect(closers.filter(event => event.type === 'step/end')).toHaveLength(type === 'step/end' ? 0 : 1) + expect(closers.at(-1)).toMatchObject({ type: 'turn/end', data: { reason: { kind: 'forked' } } }) + for (const result of results) { + const text = result.data.message.content[0] + if (text?.type !== 'text') throw new Error('fork result has no text') + expect(text.text).toContain('The parent session may have') + } + const inheritedResults = source.slice(0, boundary.seq + 1).filter(event => event.type === 'tool/result') + const expectedResults = [...inheritedResults, ...results].map(event => event.data.message) + const { agent: forked } = await ctx.agents.create({ + sessionId: SessionId('paired-child-agent'), seed: child.snapshotEvents(), + inheritedEventCount: child.inheritedEventCount, meta: { isSeeded: true }, + agentOptions: { provider: 'mock', model: 'mock' }, + }) + send(forked, 'continue this branch') + await waitForIdle(ctx, forked) + const request = adapter.requests[2] + if (request === undefined) throw new Error('child never reached the adapter') + expectPairedTools(request.messages) + expect(request.messages.filter(message => message.role === 'tool')).toEqual(expectedResults) + expect(expectedResults.map(message => message.source.callId)).toEqual([ToolCallId('call-first'), ToolCallId('call-second')]) + expect(() => { + expectPairedTools(request.messages.filter(message => ( + message.role !== 'tool' || message.source.callId !== ToolCallId('call-second') + ))) + }).toThrow() + expect(executions).toEqual(['first', 'second']) + expect(parent.session.snapshotEvents()).toEqual(source) + expect(forked.session.deriveMessages().at(-1)?.content).toEqual([{ type: 'text', text: 'child complete' }]) + } finally { + await ctx.fiber.dispose() + } + }) }) describe('discriminated SessionEvent narrows without casts', () => { @@ -1144,12 +1297,10 @@ describe('tool result call identity', () => { // And deriveMessages pairs the tool-result with the assistant tool-call: // the derived tool-result block's toolCallId equals the original call.id. const messages = agent.session.deriveMessages() - const toolResultBlock = messages - .flatMap(m => m.content) - .find(b => b.type === 'tool-result') - expect(toolResultBlock?.type).toBe('tool-result') - if (toolResultBlock?.type === 'tool-result') { - expect(toolResultBlock.toolCallId).toBe(ToolCallId('c1')) + const toolResultMessage = messages.find(m => m.role === 'tool') + expect(toolResultMessage?.role).toBe('tool') + if (toolResultMessage?.role === 'tool') { + expect(toolResultMessage.toolCallId).toBe(ToolCallId('c1')) } }) }) diff --git a/packages/core/agent-loop/tests/coverage-edges.spec.ts b/packages/core/agent-loop/tests/coverage-edges.spec.ts index 1fa24977b2..38387dc3ad 100644 --- a/packages/core/agent-loop/tests/coverage-edges.spec.ts +++ b/packages/core/agent-loop/tests/coverage-edges.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import LlmRuntime, { createUserMessage, ToolCallId, LlmError, StreamChunk, errorChain } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, TurnEndReason } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' @@ -11,6 +12,12 @@ import AgentLoop from '@deepseek-ai/dsh-agent-loop' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + function driverDone(agent: Agent): Promise { return (agent as Agent & { done: Promise }).done } @@ -237,7 +244,7 @@ describe('structured tool error propagation (the runtime-validation Agent Note, await waitForIdle(ctx, agent) const toolResult = agent.session.snapshotEvents().find(e => e.type === 'tool/result') - expect(toolResult?.type === 'tool/result' && toolResult.data.message.content[0].isError).toBe(true) + expect(toolResult?.type === 'tool/result' && toolResult.data.message.isError).toBe(true) expect(toolResult?.type === 'tool/result' && toolResult.data.error) .toEqual({ name: 'HarnessError', code: 'BOOM' }) }) @@ -493,7 +500,7 @@ describe('driver bookkeeping edges', () => { ctx.on('agent/turn-stopping', ({ agent: subject }) => { subject.inject(createUserMessage({ content: [{ type: 'text', text: 'do not enter the next step' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) }) diff --git a/packages/core/agent-loop/tests/fixtures/serial-created.mjs b/packages/core/agent-loop/tests/fixtures/serial-created.mjs index 3ddc41b52b..c4ed2df17c 100644 --- a/packages/core/agent-loop/tests/fixtures/serial-created.mjs +++ b/packages/core/agent-loop/tests/fixtures/serial-created.mjs @@ -14,7 +14,7 @@ export function apply(ctx) { id: randomUUID(), role: 'user', content: [{ type: 'text', text: 'Serial agent creation completed.' }], - source: { kind: 'plugin', plugin: name }, + source: { kind: `plugin:${name}` }, }) ready.add(agent) }) diff --git a/packages/core/agent-loop/tests/interception.spec.ts b/packages/core/agent-loop/tests/interception.spec.ts index 27302c53d8..352583df36 100644 --- a/packages/core/agent-loop/tests/interception.spec.ts +++ b/packages/core/agent-loop/tests/interception.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import LlmRuntime, { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, type SessionEvent, @@ -19,6 +20,17 @@ import AgentLoop from '@deepseek-ai/dsh-agent-loop' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'a': { kind: 'a' } & ContextFormed + 'accepted source': { kind: 'accepted source' } & ContextFormed + 'b': { kind: 'b' } & ContextFormed + 'native-guard': { kind: 'native-guard' } & ContextFormed + 'p': { kind: 'p' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + } +} + /** * The interception points introduced by the hooks taxonomy: `agent/pre-step`, * `agent/created`, `agent/turn-stopping`, and the @@ -132,7 +144,7 @@ describe('agent/pre-step', () => { }) const input: UserMessage = createUserMessage({ content: [{ type: 'text', text: 'accepted text' }], - source: { kind: 'plugin', plugin: 'accepted source' }, + source: { kind: 'accepted source' }, }) const idle = waitForIdle(ctx, agent) @@ -143,7 +155,9 @@ describe('agent/pre-step', () => { if (block?.type === 'text') block.text = 'caller mutation' }).toThrow(TypeError) expect(() => { - if (input.source.kind === 'plugin') input.source.plugin = 'caller mutation' + if (input.source.kind === 'accepted source') { + (input.source as unknown as { plugin?: string }).plugin = 'caller mutation' + } }).toThrow(TypeError) decision.resolve({ kind: 'enter', messages: [input] }) await idle @@ -152,7 +166,7 @@ describe('agent/pre-step', () => { expect(observed[0]).not.toBe(input) expect(observed[0]).toMatchObject({ content: [{ type: 'text', text: 'accepted text' }], - source: { kind: 'plugin', plugin: 'accepted source' }, + source: { kind: 'accepted source' }, }) const userMsg = events(agent).find(event => event.type === 'user/message') expect(userMsg?.type === 'user/message' && userMsg.data).toEqual(input) @@ -189,7 +203,7 @@ describe('agent/pre-step', () => { kind: 'enter', messages: [...messages, createUserMessage({ content: [{ type: 'text', text: 'extra ctx' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })) @@ -198,10 +212,10 @@ describe('agent/pre-step', () => { const log = events(agent) const userMsg = log.find(e => e.type === 'user/message' && e.data.source.kind === 'user') - const ctxMsg = log.find(e => e.type === 'user/message' && e.data.source.kind === 'plugin') + const ctxMsg = log.find(e => e.type === 'user/message' && e.data.source.kind !== 'user') expect(userMsg).toBeDefined() expect(ctxMsg?.type === 'user/message' && ctxMsg.data.content).toEqual([{ type: 'text', text: 'extra ctx' }]) - expect(ctxMsg?.type === 'user/message' && ctxMsg.data.source).toEqual({ kind: 'plugin', plugin: 'test' }) + expect(ctxMsg?.type === 'user/message' && ctxMsg.data.source).toEqual({ kind: 'test' }) const sent = JSON.stringify(adapter.requests[0]!.messages) expect(sent).toContain('extra ctx') }) @@ -216,7 +230,7 @@ describe('agent/pre-step', () => { ctx.on('agent/turn-stopping', ({ agent: subject }) => { subject.inject(createUserMessage({ content: [{ type: 'text', text: 'pending context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) }) ctx.on('agent/pre-step', async ({ step }, next) => { @@ -280,7 +294,7 @@ describe('agent/pre-step', () => { agent.inject(createUserMessage({ content: [{ type: 'text', text: 'attached context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) agent.steer(createUserMessage({ content: [{ type: 'text', text: 'pre-step steering' }], source: { kind: 'user' } })) expect(events(agent).some(event => event.type === 'user/message')).toBe(false) @@ -334,7 +348,7 @@ describe('agent/pre-step', () => { await entered.promise agent.inject(createUserMessage({ content: [{ type: 'text', text: 'staged context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) agent.steer(createUserMessage({ content: [{ type: 'text', text: 'staged steering' }], source: { kind: 'user' } })) decision.resolve({ kind: 'reject' }) @@ -387,7 +401,7 @@ describe('agent/pre-step', () => { message.content.some(block => block.type === 'text' && block.text === 'blocked prompt'))) { subject.inject(createUserMessage({ content: [{ type: 'text', text: 'earlier state change' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) subject.steer(createUserMessage({ content: [{ type: 'text', text: 'earlier steering' }], @@ -439,7 +453,7 @@ describe('agent/pre-step', () => { await entered.promise agent.inject(createUserMessage({ content: [{ type: 'text', text: 'independent context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) decision.resolve({ kind: 'reject' }) await idle @@ -579,7 +593,7 @@ describe('agent/created', () => { const ctx = await harness(adapter) ctx.on('agent/created', ({ agent }) => { - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'session preamble' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'session preamble' }], source: { kind: 'test' } })) }) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -589,8 +603,8 @@ describe('agent/created', () => { // the injected context reached the model on the first (only) request expect(JSON.stringify(adapter.requests[0]!.messages)).toContain('session preamble') // and is recorded with the plugin source, never mislabeled as a user prompt - const ctxMsg = events(agent).find(e => e.type === 'user/message' && e.data.source.kind === 'plugin') - expect(ctxMsg?.type === 'user/message' && ctxMsg.data.source).toEqual({ kind: 'plugin', plugin: 'test' }) + const ctxMsg = events(agent).find(e => e.type === 'user/message' && e.data.source.kind !== 'user') + expect(ctxMsg?.type === 'user/message' && ctxMsg.data.source).toEqual({ kind: 'test' }) }) it('a throwing creation listener rolls back the agent before its first turn', async () => { @@ -632,7 +646,7 @@ describe('tool additionalContexts buffering across a step', () => { kind: 'accept', additionalContexts: [createUserMessage({ content: [{ type: 'text', text: `ctx-${exec.callId}` }], - source: { kind: 'plugin', plugin: 'p' }, + source: { kind: 'p' }, })], })) @@ -641,7 +655,7 @@ describe('tool additionalContexts buffering across a step', () => { // Event order in the log: both tool/results, THEN both injected contexts — // never interleaved (which would break tool-call/result adjacency). - const injected = events(agent).filter(e => e.type === 'user/message' && e.data.source.kind === 'plugin') + const injected = events(agent).filter(e => e.type === 'user/message' && e.data.source.kind !== 'user') const seqs = events(agent) const firstResult = seqs.findIndex(e => e.type === 'tool/result') const lastResult = seqs.map(e => e.type).lastIndexOf('tool/result') @@ -663,10 +677,10 @@ describe('tool additionalContexts buffering across a step', () => { name: 'composite', description: 'composite', parameters: {}, async execute(_args, exec) { exec.deferContext(createUserMessage({ - content: [{ type: 'text', text: 'nested-a' }], source: { kind: 'plugin', plugin: 'a' }, + content: [{ type: 'text', text: 'nested-a' }], source: { kind: 'a' }, })) exec.deferContext(createUserMessage({ - content: [{ type: 'text', text: 'nested-b' }], source: { kind: 'plugin', plugin: 'b' }, + content: [{ type: 'text', text: 'nested-b' }], source: { kind: 'b' }, })) return [{ type: 'text', text: 'outer result' }] }, @@ -678,12 +692,12 @@ describe('tool additionalContexts buffering across a step', () => { const log = events(agent) const resultIndex = log.findIndex(event => event.type === 'tool/result') - const contextEvents = log.filter(event => event.type === 'user/message' && event.data.source.kind === 'plugin') + const contextEvents = log.filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(resultIndex).toBeGreaterThanOrEqual(0) expect(log.findIndex(event => event === contextEvents[0])).toBeGreaterThan(resultIndex) expect(contextEvents.map(event => event.type === 'user/message' && event.data.source)).toEqual([ - { kind: 'plugin', plugin: 'a' }, - { kind: 'plugin', plugin: 'b' }, + { kind: 'a' }, + { kind: 'b' }, ]) }) }) @@ -709,9 +723,9 @@ describe('tools/pre-execute gate (native-plugin permission pattern, end-to-end t expect(ran).toBe(false) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) expect(result?.type === 'tool/result' - && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('blocked dangerous tool'))).toBe(true) + && result.data.message.content.some(b => b.type === 'text' && b.text.includes('blocked dangerous tool'))).toBe(true) }) }) @@ -724,7 +738,7 @@ describe('worked example: a native hook plugin is just a cordis plugin on the se apply(ctx: Context) { // 1. SessionStart: seed a standing instruction. ctx.on('agent/created', ({ agent, source }) => { - agent.inject(createUserMessage({ content: [{ type: 'text', text: `policy active (started: ${source})` }], source: { kind: 'plugin', plugin: 'native-guard' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: `policy active (started: ${source})` }], source: { kind: 'native-guard' } })) }) // 2. PreStep: reject a forbidden prompt, annotate the rest. ctx.on('agent/pre-step', async ({ messages }, next): Promise => { @@ -745,7 +759,7 @@ describe('worked example: a native hook plugin is just a cordis plugin on the se const decision = await next() if (decision.kind === 'accept') { return { kind: 'accept', additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'audited' }], source: { kind: 'plugin', plugin: 'native-guard' }, + content: [{ type: 'text', text: 'audited' }], source: { kind: 'native-guard' }, })] } } return decision @@ -768,13 +782,13 @@ describe('worked example: a native hook plugin is just a cordis plugin on the se const log = events(agent) // session-start preamble injected - expect(log.some(e => e.type === 'user/message' && e.data.source.kind === 'plugin' + expect(log.some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('policy active (started: startup)')))).toBe(true) // prompt allowed → user-sourced user/message recorded expect(log.some(e => e.type === 'user/message' && e.data.source.kind === 'user')).toBe(true) // tool ran (echo allowed) and post-execute attached "audited" context - expect(log.some(e => e.type === 'tool/result' && !e.data.message.content[0].isError)).toBe(true) - expect(log.some(e => e.type === 'user/message' && e.data.source.kind === 'plugin' + expect(log.some(e => e.type === 'tool/result' && !e.data.message.isError)).toBe(true) + expect(log.some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text === 'audited'))).toBe(true) // NO hook/* events — a native plugin needs none expect(log.some(e => e.type.startsWith('hook/'))).toBe(false) diff --git a/packages/core/agent-loop/tests/invariant.spec.ts b/packages/core/agent-loop/tests/invariant.spec.ts index 6a71629711..14ca873c8c 100644 --- a/packages/core/agent-loop/tests/invariant.spec.ts +++ b/packages/core/agent-loop/tests/invariant.spec.ts @@ -4,6 +4,13 @@ import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import InvariantRegistry from '@deepseek-ai/dsh-invariants' import * as AgentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant' import { createUserMessage, markAgentLoopRequest, type GenerateOptions } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' + +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'x': { kind: 'x' } & ContextFormed + } +} async function setup(): Promise { const ctx = new Context() @@ -45,7 +52,7 @@ describe('request-reconstruction invariant', () => { it('includes context appended inside the open step before dispatch', async () => { const { ctx, session } = await requestSetup() session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: '[step context]' }], source: { kind: 'plugin', plugin: 'x' }, + content: [{ type: 'text', text: '[step context]' }], source: { kind: 'x' }, }), { surfaceOp: 'append' }) const options = loopRequest({ model: 'm', diff --git a/packages/core/agent-loop/tests/loop.spec.ts b/packages/core/agent-loop/tests/loop.spec.ts index fb98a37e31..7587f1da7b 100644 --- a/packages/core/agent-loop/tests/loop.spec.ts +++ b/packages/core/agent-loop/tests/loop.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import LlmRuntime, { createUserMessage, ToolCallId, LlmError, ReasoningEffortId, StreamChunk, expandAssistantStream } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import type { GenerateOptions } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, TurnEndReason } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' @@ -11,6 +12,18 @@ import AgentLoop from '@deepseek-ai/dsh-agent-loop' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { MockAdapter, maxTokensResponse, textResponse, toolCallResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'loop-test': { kind: 'loop-test' } & ContextFormed + 'max-tokens-test': { kind: 'max-tokens-test' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + 'test-compaction': { kind: 'test-compaction' } & ContextFormed + 'test-context': { kind: 'test-context' } & ContextFormed + 'watcher': { kind: 'watcher' } & ContextFormed + 'x': { kind: 'x' } & ContextFormed + } +} + function driverDone(agent: Agent): Promise { return (agent as Agent & { done: Promise }).done } @@ -496,12 +509,11 @@ describe('agent loop', () => { // the second request's derived history contains the tool result const secondMessages = adapter.requests[1]!.messages - const toolResultMessage = secondMessages.find(m => - m.content.some(b => b.type === 'tool-result')) + const toolResultMessage = secondMessages.find(m => m.role === 'tool') expect(toolResultMessage).toBeDefined() - const block = toolResultMessage!.content.find(b => b.type === 'tool-result')! - expect(block).toMatchObject({ toolCallId: 'c1', isError: false }) - expect((block).content).toEqual([{ type: 'text', text: 'echo: ping' }]) + const message = toolResultMessage! + expect(message).toMatchObject({ toolCallId: 'c1', isError: false }) + expect(message.content).toEqual([{ type: 'text', text: 'echo: ping' }]) // session log records call + result const types = agent.session.snapshotEvents().map(e => e.type) @@ -683,8 +695,7 @@ describe('agent loop', () => { const agent = await ctx.agentLoop.create(SessionId('a-runtime-context'), { provider: 'mock', model: 'mock' }) const contextEvents = () => agent.session.snapshotEvents().flatMap(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt' + && event.data.source.kind === 'runtime-context' ? [event] : []) @@ -737,12 +748,11 @@ describe('agent loop', () => { await waitForIdle(ctx, agent) const contextEvent = agent.session.snapshotEvents().find(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt') + && event.data.source.kind === 'runtime-context') if (contextEvent?.type !== 'user/message') throw new Error('first turn did not materialize runtime context') agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted summary' }], - source: { kind: 'plugin', plugin: 'test-compaction' }, + source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: contextEvent.seq, endSeq: contextEvent.seq }, sourceEventSeqs: [contextEvent.seq], @@ -752,14 +762,12 @@ describe('agent loop', () => { await waitForIdle(ctx, agent) const runtimeContexts = agent.session.snapshotEvents().flatMap(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt' + && event.data.source.kind === 'runtime-context' ? [event] : []) expect(runtimeContexts).toHaveLength(2) expect(adapter.requests[1]?.messages.some(message => - message.source.kind === 'plugin' - && message.source.plugin === '@deepseek-ai/dsh-system-prompt')).toBe(true) + message.role === 'user' && message.source?.kind === 'runtime-context')).toBe(true) }) it('clears compacted runtime context after the active set becomes empty', async () => { @@ -772,12 +780,11 @@ describe('agent loop', () => { await waitForIdle(ctx, agent) const contextEvent = agent.session.snapshotEvents().find(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt') + && event.data.source.kind === 'runtime-context') if (contextEvent?.type !== 'user/message') throw new Error('first turn did not materialize runtime context') agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary retaining old mode: read-only' }], - source: { kind: 'plugin', plugin: 'test-compaction' }, + source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: contextEvent.seq, endSeq: contextEvent.seq }, sourceEventSeqs: [contextEvent.seq], @@ -787,9 +794,7 @@ describe('agent loop', () => { send(agent, 'after compaction') await waitForIdle(ctx, agent) const clearing = adapter.requests[1]?.messages.find(message => - message.role === 'user' - && message.source.kind === 'plugin' - && message.source.plugin === '@deepseek-ai/dsh-system-prompt') + message.role === 'user' && message.source?.kind === 'runtime-context') expect(clearing?.content).toEqual([{ type: 'text', text: 'Current runtime context: none. Earlier runtime-context snapshots no longer apply.', @@ -802,11 +807,11 @@ describe('agent loop', () => { const agent = await ctx.agentLoop.create(SessionId('a-runtime-context-unrelated-compaction'), { provider: 'mock', model: 'mock' }) const original = agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'old context' }], - source: { kind: 'plugin', plugin: 'test-context' }, + source: { kind: 'test-context' }, }), { surfaceOp: 'append' }) agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted summary' }], - source: { kind: 'plugin', plugin: 'test-compaction' }, + source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: original.seq, endSeq: original.seq }, sourceEventSeqs: [original.seq], @@ -815,9 +820,7 @@ describe('agent loop', () => { send(agent, 'after compaction') await waitForIdle(ctx, agent) expect(adapter.requests[0]?.messages.some(message => - message.role === 'user' - && message.source.kind === 'plugin' - && message.source.plugin === '@deepseek-ai/dsh-system-prompt')).toBe(false) + message.role === 'user' && message.source?.kind === 'runtime-context')).toBe(false) }) it('replaces a malformed retained runtime-context message with the current complete snapshot', async () => { @@ -827,15 +830,14 @@ describe('agent loop', () => { const agent = await ctx.agentLoop.create(SessionId('a-runtime-context-malformed'), { provider: 'mock', model: 'mock' }) agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'broken' }, { type: 'text', text: 'snapshot' }], - source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, + source: { kind: 'runtime-context' }, }), { surfaceOp: 'append' }) send(agent, 'repair context') await waitForIdle(ctx, agent) const runtimeContexts = agent.session.snapshotEvents().flatMap(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt' + && event.data.source.kind === 'runtime-context' ? [event] : []) expect(runtimeContexts).toHaveLength(2) @@ -961,7 +963,7 @@ describe('agent loop', () => { const ctx = await harness(adapter) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'file changed: a.ts' }], source: { kind: 'plugin', plugin: 'watcher' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'file changed: a.ts' }], source: { kind: 'watcher' } })) expect(agent.status).toBe('idle') expect(adapter.requests).toHaveLength(0) expect(agent.session.snapshotEvents().filter(event => event.type === 'turn/start')).toHaveLength(0) @@ -972,7 +974,7 @@ describe('agent loop', () => { inserted: [{ role: 'user', content: [{ type: 'text', text: 'file changed: a.ts' }], - source: { kind: 'plugin', plugin: 'watcher' }, + source: { kind: 'watcher' }, }], }, }) @@ -990,13 +992,13 @@ describe('agent loop', () => { const ctx = await harness(adapter) const agent = await ctx.agentLoop.create(SessionId('raw-context'), { provider: 'mock', model: 'mock' }) const text = 'Additional instructions from: pkg/AGENTS.md' - agent.inject(createUserMessage({ content: [{ type: 'text', text }], source: { kind: 'plugin', plugin: 'agent-instructions' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text }], source: { kind: 'agent-instructions', form: 'instructions', changes: [] } })) send(agent, 'go') await waitForIdle(ctx, agent) - const contextEvent = agent.session.snapshotEvents().find(event => event.type === 'user/message' && event.data.source.kind === 'plugin') + const contextEvent = agent.session.snapshotEvents().find(event => event.type === 'user/message' && event.data.source.kind === 'agent-instructions') expect(contextEvent?.type === 'user/message' && contextEvent.data.source) - .toEqual({ kind: 'plugin', plugin: 'agent-instructions' }) + .toEqual({ kind: 'agent-instructions', form: 'instructions', changes: [] }) const requestText = JSON.stringify(adapter.requests[0]!.messages) expect(requestText).toContain('Additional instructions from: pkg/AGENTS.md') expect(requestText).not.toContain(' { async execute() { await Promise.resolve() const first = { type: 'text' as const, text: 'mid-turn notice' } - agent.inject(createUserMessage({ content: [first], source: { kind: 'plugin', plugin: 'x' } })) + agent.inject(createUserMessage({ content: [first], source: { kind: 'x' } })) first.text = 'mutated after inject' - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'second notice' }], source: { kind: 'plugin', plugin: 'x' } })) - visibleDuringTool = agent.session.snapshotEvents().some(e => e.type === 'user/message' && e.data.source.kind === 'plugin') + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'second notice' }], source: { kind: 'x' } })) + visibleDuringTool = agent.session.snapshotEvents().some(e => e.type === 'user/message' && e.data.source.kind === 'x') return [{ type: 'text', text: 'ok' }] }, })) @@ -1035,7 +1037,7 @@ describe('agent loop', () => { const turnStarts = agent.session.snapshotEvents().filter(e => e.type === 'turn/start') expect(turnStarts).toHaveLength(1) const result = agent.session.snapshotEvents().find(e => e.type === 'tool/result')! - const contexts = agent.session.snapshotEvents().filter(e => e.type === 'user/message' && e.data.source.kind === 'plugin') + const contexts = agent.session.snapshotEvents().filter(e => e.type === 'user/message' && e.data.source.kind === 'x') expect(contexts).toHaveLength(2) expect(result.seq).toBeLessThan(contexts[0]!.seq) expect(contexts.flatMap(event => event.type === 'user/message' ? event.data.content : [])) @@ -1045,8 +1047,7 @@ describe('agent loop', () => { ]) const secondRequest = adapter.requests[1]!.messages - const resultIndex = secondRequest.findIndex(message => - message.content.some(block => block.type === 'tool-result')) + const resultIndex = secondRequest.findIndex(message => message.role === 'tool') const contextIndexes = secondRequest.flatMap((message, index) => message.content.some(block => block.type === 'text' && (block.text.includes('mid-turn notice') || block.text.includes('second notice'))) @@ -1070,7 +1071,7 @@ describe('agent loop', () => { parameters: {}, async execute() { expect(() => { - agent.inject(createUserMessage({ content: [{ type: 'text', text: 'invalid' }], source: { kind: 'plugin', plugin: 'test', bigint: 1n } as never })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: 'invalid' }], source: { kind: 'test', bigint: 1n } as never })) }).toThrow('agent context must be losslessly JSON-serializable') return [{ type: 'text', text: 'rejected invalid context' }] }, @@ -1079,7 +1080,7 @@ describe('agent loop', () => { send(agent, 'go') await waitForIdle(ctx, agent) - expect(agent.session.snapshotEvents().some(event => event.type === 'user/message' && event.data.source.kind === 'plugin')).toBe(false) + expect(agent.session.snapshotEvents().some(event => event.type === 'user/message' && event.data.source.kind === 'test')).toBe(false) }) it('agent/turn-stopping can steer another step (/loop pattern)', async () => { @@ -1095,7 +1096,7 @@ describe('agent loop', () => { ctx.on('session/event', (_session, event) => { if (event.type === 'step/end') steps++ }) ctx.on('agent/turn-stopping', ({ agent: subject }) => { if (steps < 3) { - subject.steer(createUserMessage({ content: [{ type: 'text', text: 'continue' }], source: { kind: 'plugin', plugin: 'loop-test' } })) + subject.steer(createUserMessage({ content: [{ type: 'text', text: 'continue' }], source: { kind: 'loop-test' } })) } }) @@ -1323,7 +1324,7 @@ describe('agent loop', () => { // (step 2 is a plain stop with no tool calls → stops). ctx.on('agent/turn-stopping', ({ agent: subject }) => { if (steps < 2) { - subject.steer(createUserMessage({ content: [{ type: 'text', text: 'continue after truncation' }], source: { kind: 'plugin', plugin: 'max-tokens-test' } })) + subject.steer(createUserMessage({ content: [{ type: 'text', text: 'continue after truncation' }], source: { kind: 'max-tokens-test' } })) } }) @@ -1352,7 +1353,7 @@ describe('agent loop', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'continue after truncation' }], - source: { kind: 'plugin', plugin: 'max-tokens-test' }, + source: { kind: 'max-tokens-test' }, }, ]) // A max-token step is sticky: the later completed step must not @@ -1640,7 +1641,7 @@ describe('agent loop', () => { const idle = waitForIdle(ctx, agent) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'user message' }], source: { kind: 'user' } })) await Promise.resolve() - agent.followup(createUserMessage({ content: [{ type: 'text', text: 'plugin message' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.followup(createUserMessage({ content: [{ type: 'text', text: 'plugin message' }], source: { kind: 'test' } })) await idle const turns = agent.session.snapshotEvents().filter(event => event.type === 'turn/start') @@ -1650,7 +1651,7 @@ describe('agent loop', () => { expect(turns).toHaveLength(2) expect(sources).toEqual([ { kind: 'user' }, - { kind: 'plugin', plugin: 'test' }, + { kind: 'test' }, ]) }) diff --git a/packages/core/agent-loop/tests/properties.spec.ts b/packages/core/agent-loop/tests/properties.spec.ts index 68e170f27e..daea36f629 100644 --- a/packages/core/agent-loop/tests/properties.spec.ts +++ b/packages/core/agent-loop/tests/properties.spec.ts @@ -74,7 +74,7 @@ function recordStatus(ctx: Context, agent: Agent): { seen: string[]; dispose: () function userMessageTexts(agent: Agent): string[] { return agent.session.snapshotEvents() .filter(e => e.type === 'user/message') - .map(e => (e.data as { content: { type: string; text?: string }[] }).content.map(b => b.text ?? '').join('')) + .map(e => e.data.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('')) } function turnNumbers(agent: Agent): number[] { diff --git a/packages/core/agent-loop/tests/request-reconstruction.spec.ts b/packages/core/agent-loop/tests/request-reconstruction.spec.ts index 2450a21999..69014d400d 100644 --- a/packages/core/agent-loop/tests/request-reconstruction.spec.ts +++ b/packages/core/agent-loop/tests/request-reconstruction.spec.ts @@ -9,6 +9,7 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import LlmRuntime, { createUserMessage, LlmError, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, LlmModelReasoningInfo, LlmResolvedModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, foldRequestHeader } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime, { defineContentToolFixture } from '@deepseek-ai/dsh-tools' @@ -18,6 +19,14 @@ import AgentLoop from '@deepseek-ai/dsh-agent-loop' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'outer-wrapper': { kind: 'outer-wrapper' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + 'test-compact': { kind: 'test-compact' } & ContextFormed + } +} + async function harness(adapter: MockAdapter, persona = 'stable base') { return harnessRoutes([['mock', adapter]], persona) } @@ -177,7 +186,7 @@ describe('request stability across the loop', () => { if (decision.kind === 'reject') return decision const appended = createUserMessage({ content: [{ type: 'text', text: 'appended reference context' }], - source: { kind: 'plugin', plugin: 'outer-wrapper' }, + source: { kind: 'outer-wrapper' }, }) return { ...decision, messages: [...decision.messages, appended] } }, { prepend: true }) @@ -508,7 +517,7 @@ describe('request stability across the loop', () => { const nodes = agent.session.surface.nodes agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: '[summary of turn 1]' }], - source: { kind: 'plugin', plugin: 'test-compact' }, + source: { kind: 'test-compact' }, }), { surfaceOp: { op: 'replace', startSeq: nodes[1]!, endSeq: nodes[2]! }, sourceEventSeqs: [nodes[1]!, nodes[2]!], @@ -544,7 +553,7 @@ describe('request stability across the loop', () => { if (first === undefined) throw new Error('request has no surface message to compact') subject.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: '[summary for retry]' }], - source: { kind: 'plugin', plugin: 'test-compact' }, + source: { kind: 'test-compact' }, }), { surfaceOp: { op: 'replace', startSeq: first, endSeq: first }, sourceEventSeqs: [first], @@ -694,7 +703,7 @@ describe('request stability across the loop', () => { const nodes = agent.session.surface.nodes agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: '[summary of turn 1]' }], - source: { kind: 'plugin', plugin: 'test-compact' }, + source: { kind: 'test-compact' }, }), { surfaceOp: { op: 'replace', startSeq: nodes[1]!, endSeq: nodes[2]! }, sourceEventSeqs: [nodes[1]!, nodes[2]!], @@ -742,7 +751,7 @@ describe('request stability across the loop', () => { ctx.on('agent/request', async (_payload, next) => { if (!injected) { injected = true - agent.inject(createUserMessage({ content: [{ type: 'text', text: '[late context]' }], source: { kind: 'plugin', plugin: 'test' } })) + agent.inject(createUserMessage({ content: [{ type: 'text', text: '[late context]' }], source: { kind: 'test' } })) } return next() }) @@ -752,7 +761,7 @@ describe('request stability across the loop', () => { const first = adapter.requests[0]! // The inject landed in the log after the boundary: not in THIS request… expect(first.messages.some(m => m.content.some(b => b.type === 'text' && b.text.includes('[late context]')))).toBe(false) - expect(agent.session.snapshotEvents().some(e => e.type === 'user/message' && e.data.source.kind === 'plugin')).toBe(true) + expect(agent.session.snapshotEvents().some(e => e.type === 'user/message' && e.data.source.kind !== 'user')).toBe(true) send(agent, 'second') await waitForIdle(ctx, agent) @@ -771,7 +780,7 @@ describe('request stability across the loop', () => { // request content in place. The freeze turns it into a loud error. options.messages.push(createUserMessage({ content: [{ type: 'text', text: 'sneaky' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) return next() }) diff --git a/packages/core/agent-loop/tests/resume.spec.ts b/packages/core/agent-loop/tests/resume.spec.ts index 9a9d80c91b..9a5326df9a 100644 --- a/packages/core/agent-loop/tests/resume.spec.ts +++ b/packages/core/agent-loop/tests/resume.spec.ts @@ -5,6 +5,7 @@ import { appendFile, mkdtemp, readdir, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import LlmRuntime from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionLogOffset, SessionSeq, Session, SessionId, TOOL_OUTCOME_UNKNOWN } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' @@ -17,6 +18,12 @@ import AgentLoop from '@deepseek-ai/dsh-agent-loop' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { MockAdapter, textResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'tool-bash': { kind: 'tool-bash' } & ContextFormed + } +} + const dirs: string[] = [] afterEach(async () => { for (const d of dirs.splice(0)) await rm(d, { recursive: true, force: true }) }) @@ -943,7 +950,7 @@ describe('the session-persistence Agent Note: AgentLoop factory create/resume', const a1 = (await ctx1.agents.create({ sessionId: SessionId('inject-sess'), meta: { cwd: '/w' }, agentOptions: { provider: 'mock', model: 'mock' } })).agent a1.followup(createUserMessage({ content: [{ type: 'text', text: 'q' }], source: { kind: 'user' } })) await waitForIdle(ctx1, a1) - a1.inject(createUserMessage({ content: [{ type: 'text', text: 'background job 42 finished' }], source: { kind: 'plugin', plugin: 'tool-bash' } })) + a1.inject(createUserMessage({ content: [{ type: 'text', text: 'background job 42 finished' }], source: { kind: 'tool-bash' } })) await a1.whenIdle() await ctx1.sessions.flush(a1.session) // Simulate a wedged first lifecycle: a graceful dispose would durably diff --git a/packages/core/agent-loop/tests/runtime-context.spec.ts b/packages/core/agent-loop/tests/runtime-context.spec.ts index 37c13bdc60..2883d1f7b0 100644 --- a/packages/core/agent-loop/tests/runtime-context.spec.ts +++ b/packages/core/agent-loop/tests/runtime-context.spec.ts @@ -1,15 +1,22 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import { RuntimeContextProjection } from '../src/runtime-context.ts' -const SOURCE = '@deepseek-ai/dsh-system-prompt' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test-compaction': { kind: 'test-compaction' } & ContextFormed + } +} + +const SOURCE = 'runtime-context' function contextMessage(text: string) { return createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: SOURCE }, + source: { kind: SOURCE }, }) } @@ -22,7 +29,7 @@ describe('RuntimeContextProjection', () => { const shadowed = session.append('user/message', contextMessage('shadowed'), { surfaceOp: 'append' }) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'test-compaction' }, + source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: shadowed.seq, endSeq: shadowed.seq }, sourceEventSeqs: [shadowed.seq], @@ -32,8 +39,7 @@ describe('RuntimeContextProjection', () => { expect(session.surface.nodes).toContain(retained.seq) expect(projection.project('retained', [])).toBeUndefined() expect(projection.project('next', [{ name: 'sandbox:policy', text: 'policy' }])?.source).toEqual({ - kind: 'plugin', - plugin: SOURCE, + kind: SOURCE, form: 'snapshot', sections: [{ name: 'sandbox:policy', text: 'policy' }], }) diff --git a/packages/core/agent-loop/tests/system-prompt-admission.spec.ts b/packages/core/agent-loop/tests/system-prompt-admission.spec.ts index d3702147f6..25051e26ee 100644 --- a/packages/core/agent-loop/tests/system-prompt-admission.spec.ts +++ b/packages/core/agent-loop/tests/system-prompt-admission.spec.ts @@ -10,6 +10,12 @@ import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime, { defineContentToolFixture } from '@deepseek-ai/dsh-tools' import { MockAdapter, textResponse } from './mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test-compaction': { kind: 'test-compaction' } & import('@deepseek-ai/dsh-llm').ContextFormed + } +} + const contexts: Context[] = [] afterEach(async () => { for (const ctx of contexts.splice(0)) await ctx.fiber.dispose() @@ -151,7 +157,7 @@ describe('prepared-route prompt admission', () => { const start = retainOlder ? latest : nodes[1]! const replaced = nodes.slice(nodes.indexOf(start), nodes.indexOf(latest) + 1) h.agent.session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'compacted history' }], source: { kind: 'plugin', plugin: 'test-compaction' }, + content: [{ type: 'text', text: 'compacted history' }], source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: start, endSeq: latest }, sourceEventSeqs: replaced }) // A retry must retain the assembly accepted for this step, not pick up new sections. h.setPrompt('not admitted until next step') @@ -215,11 +221,11 @@ describe('prepared-route prompt admission', () => { [{ type: 'text', text: 'second' }], notice, ]) const notices = h.agent.session.snapshotEvents().filter(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' && event.data.source.plugin === 'model-selection') + && event.data.source.kind === 'model-selection') expect(notices).toHaveLength(1) expect(notices[0]!.data).toMatchObject({ content: notice, - source: { kind: 'plugin', plugin: 'model-selection', form: 'notice', summary: 'plain/model → capable/model' }, + source: { kind: 'model-selection', form: 'notice', summary: 'plain/model → capable/model' }, }) }) @@ -236,7 +242,7 @@ describe('prepared-route prompt admission', () => { if (agent === resumed && replace) { const seq = agent.session.surface.nodes.find(seq => agent.session.eventAt(seq)?.type === 'user/message')! agent.session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'compacted history' }], source: { kind: 'plugin', plugin: 'test-compaction' }, + content: [{ type: 'text', text: 'compacted history' }], source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: seq, endSeq: seq }, sourceEventSeqs: [seq] }) } return next() diff --git a/packages/core/agent-loop/tests/system-prompt-projection.spec.ts b/packages/core/agent-loop/tests/system-prompt-projection.spec.ts index c50b064557..65ec74c486 100644 --- a/packages/core/agent-loop/tests/system-prompt-projection.spec.ts +++ b/packages/core/agent-loop/tests/system-prompt-projection.spec.ts @@ -6,7 +6,12 @@ import type { Session, SurfaceIntent } from '@deepseek-ai/dsh-session' import { SystemPromptProjection } from '../src/runtime-context.ts' import type { SystemPromptCommit, SystemPromptDecisionInput } from '../src/runtime-context.ts' -const SOURCE = '@deepseek-ai/dsh-system-prompt' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test-compaction': { kind: 'test-compaction' } & import('@deepseek-ai/dsh-llm').ContextFormed + } +} + const REPLACING: SystemPromptDecisionInput = { inHistory: false, startsSeries: false } const CONTINUING: SystemPromptDecisionInput = { inHistory: true, startsSeries: false } const NEW_SERIES: SystemPromptDecisionInput = { inHistory: true, startsSeries: true } @@ -39,13 +44,13 @@ describe('SystemPromptProjection', () => { const ctx = await sessionStore() try { const session = ctx.sessions.create(SessionId('system-prompt-multiblock')) - const base = createSystemMessage('old', SOURCE) + const base = createSystemMessage('old') session.append('system/message', { turn: 1, step: 1, message: { ...base, content: [{ type: 'text', text: 'old ' }, { type: 'text', text: 'instructions' }], } }, { surfaceOp: 'append' }) appendUser(session, 'hello') session.append('system/message', { turn: 1, step: 1, message: { - ...createSystemMessage('tail', SOURCE), content: [{ type: 'reasoning', text: 'retained content' }], + ...createSystemMessage('tail'), content: [{ type: 'reasoning', text: 'retained content' }], } }, { surfaceOp: 'append' }) const projection = new SystemPromptProjection(session) for (const update of projection.project('', CONTINUING)) commit(session, 2, update) @@ -64,7 +69,7 @@ describe('SystemPromptProjection', () => { const first = projection.project('v1', REPLACING)[0] expect(first?.intent).toEqual({ surfaceOp: 'append' }) expect(first?.message.role).toBe('system') - expect(first?.message.source).toEqual({ kind: 'plugin', plugin: SOURCE }) + expect(first?.message.source).toEqual({ kind: 'system-prompt' }) const head = commit(session, 1, first) appendUser(session, 'hello') @@ -114,16 +119,16 @@ describe('SystemPromptProjection', () => { it('reads the surviving system node from the log, including one restored as "no prompt"', async () => { const ctx = await sessionStore() const session = ctx.sessions.create(SessionId('system-prompt-replay')) - const stale = session.append('system/message', { turn: 1, step: 1, message: createSystemMessage('stale', SOURCE) }, { surfaceOp: 'append' }) + const stale = session.append('system/message', { turn: 1, step: 1, message: createSystemMessage('stale') }, { surfaceOp: 'append' }) appendUser(session, 'hello') - const current = session.append('system/message', { turn: 2, step: 1, message: createSystemMessage('current', SOURCE) }, replaceOf(stale.seq)) + const current = session.append('system/message', { turn: 2, step: 1, message: createSystemMessage('current') }, replaceOf(stale.seq)) const projection = new SystemPromptProjection(session) expect(projection.project('current', REPLACING)[0]).toBeUndefined() expect(projection.project('next', REPLACING)[0]?.intent).toEqual(replaceOf(current.seq)) const emptySession = ctx.sessions.create(SessionId('system-prompt-empty-replay')) - const empty = emptySession.append('system/message', { turn: 1, step: 1, message: createSystemMessage('', SOURCE) }, { surfaceOp: 'append' }) + const empty = emptySession.append('system/message', { turn: 1, step: 1, message: createSystemMessage('') }, { surfaceOp: 'append' }) appendUser(emptySession, 'hello') const emptyProjection = new SystemPromptProjection(emptySession) expect(emptyProjection.project('', REPLACING)[0]).toBeUndefined() @@ -143,7 +148,7 @@ describe('SystemPromptProjection', () => { session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'test-compaction' }, + source: { kind: 'test-compaction' }, }), replaceOf(node.seq)) expect(projection.project('late prompt', REPLACING)[0]?.intent).toEqual({ surfaceOp: 'append' }) }) diff --git a/packages/core/agent-loop/tests/tool-calls.spec.ts b/packages/core/agent-loop/tests/tool-calls.spec.ts index 27118dacb1..29c4cc3230 100644 --- a/packages/core/agent-loop/tests/tool-calls.spec.ts +++ b/packages/core/agent-loop/tests/tool-calls.spec.ts @@ -9,6 +9,7 @@ import { createUserMessage, ToolCallId, StreamChunk } from '@deepseek-ai/dsh-ll import SessionStore, { SessionEvent, SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import LlmRuntime from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import ToolRuntime, { defineContentToolFixture, TOOL_ABORTED_BEFORE_DISPATCH, TOOL_RUNTIME_SCHEDULER, type PostToolDecision, type PreToolDecision } from '@deepseek-ai/dsh-tools' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import AgentLoop, { DEFAULT_MAX_PARALLEL_TOOL_CALLS } from '@deepseek-ai/dsh-agent-loop' @@ -17,6 +18,12 @@ import { MockAdapter, textResponse } from './mock-adapter.ts' import { PtcRuntime } from '@deepseek-ai/dsh-ptc-runtime' import type { PtcRunRequest, PtcRunResult } from '@deepseek-ai/dsh-ptc-runtime' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'p': { kind: 'p' } & ContextFormed + } +} + async function harness(adapter: MockAdapter, maxParallelToolCalls?: number) { const ctx = new Context() await ctx.plugin(LlmRuntime) @@ -258,7 +265,7 @@ describe('tool-call scheduler: model-order results despite out-of-order settleme await waitForIdle(ctx, agent) const messages = agent.session.deriveMessages() - const toolResults = messages.flatMap(m => m.content.filter(b => b.type === 'tool-result')) + const toolResults = messages.filter(m => m.role === 'tool') expect(toolResults.map(b => b.toolCallId)).toEqual([ToolCallId('c1'), ToolCallId('c2')]) }) }) @@ -406,7 +413,7 @@ describe('tool-call scheduler: ordered middleware and additional contexts', () = ctx.tools.register(gated.tool) ctx.on('tools/post-execute', async (exec, _result): Promise => ({ kind: 'accept', additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: `ctx-${exec.callId}` }], source: { kind: 'plugin', plugin: 'p' }, + content: [{ type: 'text', text: `ctx-${exec.callId}` }], source: { kind: 'p' }, })] })) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -416,11 +423,11 @@ describe('tool-call scheduler: ordered middleware and additional contexts', () = await waitForIdle(ctx, agent) const log = events(agent) - const contextTexts = log.filter(e => e.type === 'user/message' && e.data.source.kind === 'plugin') + const contextTexts = log.filter(e => e.type === 'user/message' && e.data.source.kind !== 'user') .map(e => ((e.data as { content: { text: string }[] }).content[0]!).text) expect(contextTexts).toEqual(['ctx-c1', 'ctx-c2']) const lastResult = log.findLastIndex(e => e.type === 'tool/result') - const firstContext = log.findIndex(e => e.type === 'user/message' && e.data.source.kind === 'plugin') + const firstContext = log.findIndex(e => e.type === 'user/message' && e.data.source.kind !== 'user') expect(lastResult).toBeLessThan(firstContext) }) @@ -463,11 +470,11 @@ describe('tool-call scheduler: ordered middleware and additional contexts', () = expect(post).toEqual(['c1', 'c2']) const results = events(agent).filter(e => e.type === 'tool/result') expect(results.map(e => e.data.message.source.callId)).toEqual([ToolCallId('c1'), ToolCallId('c2'), ToolCallId('c3')]) - expect((results[1]!.data.message.content[0].content[0] as { text: string }).text).toContain('blocked by policy') + expect((results[1]!.data.message.content[0] as { text: string }).text).toContain('blocked by policy') expect(results[1]!.data.error).toEqual({ name: 'AutoReviewDeniedError', code: 'AUTO_REVIEW_DENIED', reason: 'exact scope was not authorized', }) - expect((results[2]!.data.message.content[0].content[0] as { text: string }).text).toContain('pre exploded') + expect((results[2]!.data.message.content[0] as { text: string }).text).toContain('pre exploded') }) }) @@ -495,7 +502,7 @@ describe('tool-call scheduler: abort handling', () => { .toEqual([ToolCallId('c1'), ToolCallId('c2')]) expect(events(agent).filter(e => e.type === 'tool/result').map(e => ({ callId: e.data.message.source.callId, - isError: e.data.message.content[0].isError, + isError: e.data.message.isError, error: e.data.error, }))).toEqual([ { callId: ToolCallId('c1'), isError: true, error: { name: 'AbortError', code: TOOL_ABORTED_BEFORE_DISPATCH } }, @@ -527,7 +534,7 @@ describe('tool-call scheduler: abort handling', () => { .toEqual([ToolCallId('c1'), ToolCallId('c2')]) expect(events(agent).filter(e => e.type === 'tool/result').map(e => ({ callId: e.data.message.source.callId, - isError: e.data.message.content[0].isError, + isError: e.data.message.isError, error: e.data.error, }))).toEqual([ { callId: ToolCallId('c1'), isError: true, error: { name: 'AbortError', code: TOOL_ABORTED_BEFORE_DISPATCH } }, @@ -546,7 +553,7 @@ describe('tool-call scheduler: abort handling', () => { ctx.on('tools/post-execute', async (exec, _result, next): Promise => ({ ...await next(), additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: `ctx-${exec.callId}` }], source: { kind: 'plugin', plugin: 'p' }, + content: [{ type: 'text', text: `ctx-${exec.callId}` }], source: { kind: 'p' }, })], })) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -565,7 +572,7 @@ describe('tool-call scheduler: abort handling', () => { .toEqual([ToolCallId('c1'), ToolCallId('c2'), ToolCallId('c3'), ToolCallId('c4')]) expect(events(agent).filter(e => e.type === 'tool/result').slice(-2).map(e => ({ callId: e.data.message.source.callId, - isError: e.data.message.content[0].isError, + isError: e.data.message.isError, error: e.data.error, }))) .toEqual([ @@ -581,7 +588,7 @@ describe('tool-call scheduler: abort handling', () => { }, ]) const settled = events(agent).filter(e => e.type === 'tool/result' - || (e.type === 'user/message' && e.data.source.kind === 'plugin')) + || (e.type === 'user/message' && e.data.source.kind !== 'user')) expect(settled.map(e => e.type)) .toEqual(['tool/result', 'tool/result', 'tool/result', 'tool/result']) expect(agent.inbox.nextStep.map(message => message.content[0])) @@ -596,7 +603,7 @@ describe('tool-call scheduler: abort handling', () => { expect(events(agent).flatMap(e => e.type === 'user/message' - && e.data.source.kind === 'plugin' + && e.data.source.kind !== 'user' && e.data.content[0]?.type === 'text' ? [e.data.content[0].text] : [])) @@ -638,7 +645,8 @@ describe('tool-call scheduler: abort handling', () => { .toMatchObject({ message: { source: { kind: 'tool', callId: ToolCallId('c3') }, - content: [{ isError: true }], + content: [{ type: 'text', text: 'Error: tool call aborted before dispatch' }], + isError: true, }, error: { name: 'AbortError', code: TOOL_ABORTED_BEFORE_DISPATCH }, }) diff --git a/packages/core/agent/src/consumed-work.ts b/packages/core/agent/src/consumed-work.ts index b86ac836ef..55da0dbb5e 100644 --- a/packages/core/agent/src/consumed-work.ts +++ b/packages/core/agent/src/consumed-work.ts @@ -48,10 +48,11 @@ function accountsForClaim(reason: TurnEndReason): boolean { case 'interrupted': case 'error': return true - /* v8 ignore next 4 -- unreachable: the one unnamed built-in, `max-tokens`, requires a step, - * so its turn short-circuits as stepped before this call, and `TurnEndReasonMap` is - * merge-extensible, so a backend-added variant cannot be listed; an unnameable ending over - * consumed input must not read as success. */ + /* v8 ignore next 5 -- unreachable: `max-tokens` requires a step and short-circuits + * before this call; `forked` exists only in constructor seed history, while production + * callers fold an operation-owned suffix. `TurnEndReasonMap` is merge-extensible, so a + * backend-added variant cannot be listed; an unnameable ending over consumed input must + * not read as success. */ default: return true } diff --git a/packages/core/agent/src/index.ts b/packages/core/agent/src/index.ts index a7d39f6f9a..9bbdb89566 100644 --- a/packages/core/agent/src/index.ts +++ b/packages/core/agent/src/index.ts @@ -86,11 +86,10 @@ export interface CreateAgentOptions { /** Exact fork-inherited prefix length when the session metadata sets `isSeeded`. */ readonly inheritedEventCount?: SessionLogOffset /** - * Initial replay/fork history. A fork supplies a balanced completed-turn - * prefix of the parent's log. The complete seed must be contiguous from seq - * 0, carry only lossless-JSON data, and contain no open turn/step or dangling - * tool call. The factory passes it to the session's durable - * validator/snapshot boundary before publication. + * Initial replay/fork history, contiguous from seq 0 with lossless-JSON data. + * A fork supplies an exact parent prefix, its inherited marker, and closers + * for the open tail. Previously closed steps and turns remain unchanged. + * The factory validates and snapshots the seed before publication. */ readonly seed?: readonly SessionEvent[] /** Per-agent options (model, …). */ diff --git a/packages/core/agent/src/model-selection.ts b/packages/core/agent/src/model-selection.ts index 172423afc0..8921bc12a4 100644 --- a/packages/core/agent/src/model-selection.ts +++ b/packages/core/agent/src/model-selection.ts @@ -11,6 +11,12 @@ import { type ReasoningEffortId, } from '@deepseek-ai/dsh-llm' import type { PreStepDecision } from './runtime-types.ts' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'model-selection': { kind: 'model-selection' } & ContextFormed + } +} /** Complete provider, model, and optional reasoning effort selected for one live Agent. */ export interface ModelSelection { @@ -47,9 +53,8 @@ function modelSwitchNotice(previous: ModelSelection, selected: ModelSelection) { text: `[model changed: assistant turns above this point were generated by ${from}; the session continues with ${to}]`, }], source: { - kind: 'plugin' as const, - plugin: 'model-selection', - form: 'notice' as const, + kind: 'model-selection', + form: 'notice', summary: boundContextSummary(`${from} → ${to}`), }, }) diff --git a/packages/core/agent/tests/model-selection.spec.ts b/packages/core/agent/tests/model-selection.spec.ts index 5bddd71019..27b2a7bffd 100644 --- a/packages/core/agent/tests/model-selection.spec.ts +++ b/packages/core/agent/tests/model-selection.spec.ts @@ -32,7 +32,7 @@ function expectedNotice(from: string, to: string) { type: 'text', text: `[model changed: assistant turns above this point were generated by ${from}; the session continues with ${to}]`, }], - source: { kind: 'plugin', plugin: 'model-selection', form: 'notice', summary: `${from} → ${to}` }, + source: { kind: 'model-selection', form: 'notice', summary: `${from} → ${to}` }, } } diff --git a/packages/core/session/README.i18n.yaml b/packages/core/session/README.i18n.yaml index 583c52a88c..ae3352f3f1 100644 --- a/packages/core/session/README.i18n.yaml +++ b/packages/core/session/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/core/session/README.md -README.md: 8d07292287d7300b562751ad74de77397bd5b5db -README.zh.md: 28b6f1f02838420861a76409046c0e9a12bac1b5 +README.md: 06c4f1806995c2fdff78515f88a60c6e449e3a26 +README.zh.md: c52eee96af19bcd6f5a76f950026d2c191002732 diff --git a/packages/core/session/README.md b/packages/core/session/README.md index 8d07292287..06c4f18069 100644 --- a/packages/core/session/README.md +++ b/packages/core/session/README.md @@ -47,11 +47,13 @@ session.append('user/message', { role: 'user', content: [{ type: 'text', text: ' session.deriveMessages() // the derived model history ``` -Surface events (`system/message`, `user/message`, `assistant/message`, `tool/result`) require `surfaceOp` in both typed events and append input. A replacement uses exactly `{ op: 'replace', startSeq, endSeq }`, with inclusive `SessionSeq` endpoints in current surface order. An Assistant message embeds its exact compact provider stream and forbids `sourceEventSeqs`. Known log-only events forbid both metadata fields and never produce a message. +Surface events (`system/message`, `developer/message`, `user/message`, `assistant/message`, `tool/result`) require `surfaceOp` in both typed events and append input. A replacement uses exactly `{ op: 'replace', startSeq, endSeq }`, with inclusive `SessionSeq` endpoints in current surface order. An Assistant message embeds its exact compact provider stream and forbids `sourceEventSeqs`. Known log-only events forbid both metadata fields and never produce a message. + +`developer/message` stores tool-addition names and a `headerSeq` reference to an earlier `request/header`. The reference is required exactly when additions are present, and each name must identify exactly one complete schema in that header. Removals name the tool without a header reference. Historical headers remain available across restart, fork, and surface replacement; the current registry and latest header do not select an earlier addition's definition. `sourceEventSeqs` continues to describe derivation and replaced nodes. Plugins declare content-changing events with `@messageProjection` and register a pure definition through `ctx.sessions.registerMessageProjection()`. Session calls the definition before accepting an event and caches its immutable message updates. Missing definitions reject append and restore; unloading a used definition also blocks cached reads. Detached constructors and `foldSurface(events, projections)` require explicit definitions. Reconstructors pass the fold's `projectedMessages` to `deriveEventMessage()`; live instance methods apply the same projections automatically. [Plugin-owned message projections](../../../.agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.md) defines ownership and offline assembly. -Append, seed/restore, and event adoption/snapshot reject any `header.system` and exactly empty optional request-header fields (`tools: []`, `adapterDefaults: {}`) instead of normalizing input. Tool-result `data.error` is allowed only when `message.content[0].isError === true`; failure identity remains optional. Rejected appends do not change the log, derived state, or event feed. Adoption validates event-local metadata but not referenced history or replacement membership. +Append, seed/restore, and event adoption/snapshot reject any `header.system` and exactly empty optional request-header fields (`tools: []`, `adapterDefaults: {}`) instead of normalizing input. Tool-result `data.error` is allowed only when the first-class message has `isError === true`; failure identity remains optional. Rejected appends do not change the log, derived state, or event feed. Adoption validates event-local metadata but not referenced history or replacement membership. `system/message` holds the rendered system prompt: the first one is surface node 0, the prepared call capability governs admission, with a non-empty rendering consolidated at the first system node on an incapable route or appended after cached history inside a continuing `in-history` series; empty system nodes project to no message, so clearing the prompt requires logged empty replacements of all active system nodes, not just the latest; the surface fold rejects a replacement covering node 0 while it is a `system/message` unless the replacing event is itself a `system/message` over exactly that node, while later system nodes carry no protection and a compaction range may shadow them ([decision](../../../.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.md)). @@ -63,7 +65,7 @@ Session log positions use two numeric types. `SessionSeq` identifies an existing ### Fork a session -`ctx.sessions.fork(source, boundary?, childSessionId?)` selects source events through an inclusive `boundary` seq (default: the current last event), requires the prefix to end outside an open turn, and creates a live child session with lineage metadata. A tool-time delegation that must branch mid-turn clips to a completed prefix instead. +`ctx.sessions.fork(source, boundary?, childSessionId?)` copies an exact inclusive event prefix (default: the last event) from a live source. `buildForkSeed` in `dsh-session/fork` places an inherited marker after the copied events, adds missing error tool results only for the open step, and closes that step and turn with a `forked` reason. Closed steps and turns remain unchanged, including historical missing results. The marker and closers belong to the child; `inheritedEventCount` counts only the copied prefix. The logical `SessionHeader.isSeeded` field reports whether fork history exists without exposing a positional integer. `Session.inheritedEventCount` retains the exact checked `SessionLogOffset`; `ownEvents()` returns events at and after that cut, and `isOwnSeq(seq)` accepts only an existing child-owned position. A low-level seeded constructor must supply an explicit `seed` and `inheritedEventCount` because the constructor seed can contain child-owned setup events after the inherited prefix. @@ -107,7 +109,7 @@ Every append uses the shared iterative `snapshotJsonValue()` pass, which reads, ### Derived history -`deriveMessages()` caches deep-frozen projections and returns a fresh array per call. The four surface event types (`system/message`, `user/message`, `assistant/message`, `tool/result`) supply their recorded message identities and content; an empty-content system node projects to no message. Plugin-owned projections change derived content without mutating recorded messages. Replacements and projection decisions invalidate the cache. Embedded Assistant streams and `assistant/attempt` events remain replay and diagnostic data only. +`deriveMessages()` caches deep-frozen projections and returns a fresh array per call. The surface event types (`system/message`, `developer/message`, `user/message`, `assistant/message`, `tool/result`) supply their recorded message identities and content; empty-content system and developer nodes project to no message. Plugin-owned projections change derived content without mutating recorded messages. Replacements and projection decisions invalidate the cache. Embedded Assistant streams and `assistant/attempt` events remain replay and diagnostic data only. ### The request header @@ -137,7 +139,7 @@ The package-level contract is enough for most consumers; read these when you nee #### What the model sees -The model receives the complete messages from `system/message`, `user/message`, `assistant/message`, and `tool/result` surface entries with logged projections applied, the system prompt first. Identities, roles, sources, and unmodified blocks retain their original values; projections never mint identities. Direct prompts and injected context remain separate `user/message` events whose sources preserve their attribution. Embedded streams, `assistant/attempt`, boundaries, and other log-only facts add no message. +The model receives the complete messages from `system/message`, `developer/message`, `user/message`, `assistant/message`, and `tool/result` surface entries with logged projections applied, the system prompt first. Identities, roles, sources, and unmodified blocks retain their original values; projections never mint identities. Direct prompts and injected context remain separate `user/message` events whose sources preserve their attribution. Embedded streams, `assistant/attempt`, boundaries, and other log-only facts add no message. #### Token effect @@ -147,11 +149,11 @@ Appended surface entries are resent on later steps. A `replace` surface operatio Appended surface entries preserve reusable prefixes. A `replace` operation invalidates reuse from the first shadowed message even though the underlying event log stays append-only. -### Crash-repair result +### Crash-repair and fork results #### What the model sees -If recovery finds an assistant tool request with no durable `tool/call`, its synthetic `TOOL_NOT_STARTED` result says `The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.` If a durable `tool/call` has no result, its `TOOL_OUTCOME_UNKNOWN` result says `The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.` +If recovery finds an assistant tool request with no durable `tool/call`, its synthetic `TOOL_NOT_STARTED` result says `The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.` If a durable `tool/call` has no result, its `TOOL_OUTCOME_UNKNOWN` result says `The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.` Fork-generated results describe only the inherited records: the parent may have started or completed a call after the selected event. `TOOL_NOT_STARTED` means the prefix contains no start record; `TOOL_OUTCOME_UNKNOWN` means it contains a start but no result. Both tell the model to retry only read-only or idempotent operations without further checks; operations with side effects require external verification or user input. See the [fork decision](../../../.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.md). #### Token effect @@ -182,8 +184,8 @@ Logging causes no invalidation, and exact reconstruction preserves request-prefi These limits define when the session store needs special care. They are current package constraints, not a task backlog. -- **`fork()` cuts only at stable boundaries of live sessions** — the selected prefix must end outside an open turn and the source must be in the store; forking a persisted-but-unloaded session is excluded from the fork API. -- **`SESSION_FORMAT_VERSION` names the [current logical representation](../../../docs/session-format-status.md)** — the current reader rejects retired `header.system` and validates `system/message` payloads and protected-head rewrites. Historical headers and events belong to adjacent format packages; the adjacent migration chain converts supported history before constructing `Session`, and the write-open path publishes only the current-format successor. Equal-version unknown events require the envelope's explicit `ignorable` marker, which does not promise safe structural migration ([mechanism](../../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md)). +- **Live-source Store API** — persisted-but-unloaded sources use the Host observation path. Fork closes only the open tail and does not repair missing results in previously closed steps. +- **`SESSION_FORMAT_VERSION` names the [current logical representation](../../../docs/session-format-status.md)** — the current reader rejects retired `header.system` and validates `system/message` payloads and protected-head rewrites. Historical headers and events belong to adjacent format packages; the [adjacent migration chain](../../session/session-format-catalog/README.md) converts supported history before constructing `Session`, and the write-open path publishes only the current-format successor. Equal-version unknown events require the envelope's explicit `ignorable` marker, which does not promise safe structural migration ([mechanism](../../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md)). - **`TurnEndReasonMap` omits the ACP-named `refusal` / `max_turn_requests` variants** — producer-gated: they land when an adapter or the loop first emits them. - **No session tree beyond fork** — a pi-style entry tree over branched sessions is deferred unless a consumer needs more than boundary-based forking. diff --git a/packages/core/session/README.zh.md b/packages/core/session/README.zh.md index 28b6f1f028..c52eee96af 100644 --- a/packages/core/session/README.zh.md +++ b/packages/core/session/README.zh.md @@ -29,7 +29,7 @@ kind: "package-reference" ### 创建与检查会话 -`ctx.sessions.create()` 构建绑定到调用方 fiber 的实时会话;`get(id)` 与 `list()` 查找会话,`fork()` 从实时会话的稳定前缀创建子会话。 +`ctx.sessions.create()` 构建绑定到调用方 fiber 的实时会话;`get(id)` 与 `list()` 查找会话,`fork()` 从实时会话的精确前缀创建子会话。 ```text const session = ctx.sessions.create(sessionId, { meta: { cwd: '/workspace' } }) @@ -47,11 +47,13 @@ session.append('user/message', { role: 'user', content: [{ type: 'text', text: ' session.deriveMessages() // the derived model history ``` -表层事件(`system/message`、`user/message`、`assistant/message`、`tool/result`)在类型化事件与追加输入中都必须带有 `surfaceOp`。替换操作仅接受 `{ op: 'replace', startSeq, endSeq }`,端点为包含边界的 `SessionSeq`,按当前 surface 顺序解释。assistant 消息会嵌入精确、紧凑的提供方流,并禁止 `sourceEventSeqs`。已知仅日志事件禁止这两个元数据字段,且从不产生消息。 +表层事件(`system/message`、`developer/message`、`user/message`、`assistant/message`、`tool/result`)在类型化事件与追加输入中都必须带有 `surfaceOp`。替换操作仅接受 `{ op: 'replace', startSeq, endSeq }`,端点为包含边界的 `SessionSeq`,按当前 surface 顺序解释。assistant 消息会嵌入精确、紧凑的提供方流,并禁止 `sourceEventSeqs`。已知仅日志事件禁止这两个元数据字段,且从不产生消息。 + +`developer/message` 存储工具添加名称,以及指向更早 `request/header` 的 `headerSeq` 引用。仅在存在添加块时必须携带该引用,每个名称必须在所引用的请求头中恰好对应一个完整模式。移除块仅记录工具名称,不携带请求头引用。重启、fork 和 surface 替换保留历史请求头;较早添加的定义不由当前注册表或最新请求头决定。`sourceEventSeqs` 继续描述派生来源及被替换节点。 插件用 `@messageProjection` 声明修改内容的事件,并通过 `ctx.sessions.registerMessageProjection()` 注册纯处理器。Session 在接受事件前调用处理器,并缓存其不可变消息更新。缺少处理器时拒绝追加和恢复,卸载已经使用的处理器后也会拒绝读取缓存。独立构造函数和 `foldSurface(events, projections)` 必须显式接收处理器。重建函数将折叠结果的 `projectedMessages` 传给 `deriveEventMessage()`,实时实例方法自动应用相同的投影。[插件拥有消息投影](../../../.agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.zh.md)说明职责划分和离线装配。 -追加、seed/restore 与事件 adoption/snapshot 会拒绝任何 `header.system` 及恰好为空的可选请求头字段(`tools: []`、`adapterDefaults: {}`),而不规范化输入。工具结果的 `data.error` 仅在 `message.content[0].isError === true` 时允许存在;失败标识仍是可选的。被拒绝的追加不会改变日志、派生状态或事件流。Adoption 校验事件局部元数据,但不校验所引用的历史或替换端点是否属于 surface。 +追加、seed/restore 与事件 adoption/snapshot 会拒绝任何 `header.system` 及恰好为空的可选请求头字段(`tools: []`、`adapterDefaults: {}`),而不规范化输入。工具结果的 `data.error` 仅在一等消息的 `isError === true` 时允许存在;失败标识仍是可选的。被拒绝的追加不会改变日志、派生状态或事件流。Adoption 校验事件局部元数据,但不校验所引用的历史或替换端点是否属于 surface。 `system/message` 承载渲染后的系统提示词:第一条是 surface 第 0 号节点,准入依据已准备调用的能力,不具备能力的路由将非空渲染文本归并到首个系统节点,延续中的 `in-history` 序列则在缓存历史之后追加;空系统节点不投影为消息,因此清除提示词必须为所有生效的系统节点记录空内容替换,而非仅替换最新节点;当第 0 号节点是 `system/message` 时,surface 折叠拒绝覆盖它的替换,除非替换事件本身是恰好覆盖该节点的 `system/message`,而后续系统节点不受保护,压缩范围可以遮蔽它们([决策](../../../.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.zh.md))。 @@ -63,7 +65,7 @@ session.deriveMessages() // the derived model history ### 派生会话的 fork -`ctx.sessions.fork(source, boundary?, childSessionId?)` 选取截至 `boundary` 事件序号(含该事件)的源事件(默认:当前最后一个事件),要求所选前缀结束时没有开放轮次,再创建带谱系元数据的实时子会话。必须在轮次中途分支的工具时委派会裁剪到已完成前缀。 +`ctx.sessions.fork(source, boundary?, childSessionId?)` 从实时源会话复制包含切点的精确事件前缀(默认:最后一个事件)。`dsh-session/fork` 的 `buildForkSeed` 在复制事件之后放置继承标记,仅为开放步骤补缺失的错误工具结果,并以 `forked` 原因关闭步骤和轮次。已关闭的步骤与轮次保持原样,包括历史缺失结果。标记和结束事件属于子会话;`inheritedEventCount` 只统计复制的前缀。 逻辑 `SessionHeader.isSeeded` 字段报告是否存在 fork 历史,而不公开位置整数。`Session.inheritedEventCount` 保留经过校验的精确 `SessionLogOffset`;`ownEvents()` 返回从该切点开始的事件,`isOwnSeq(seq)` 只接受已存在且由子会话拥有的位置。底层带 seed 构造必须显式提供 `seed` 与 `inheritedEventCount`,因为构造 seed 可以在继承前缀之后包含子会话自有的设置事件。 @@ -107,7 +109,7 @@ session.deriveMessages() // the derived model history ### 派生历史 -`deriveMessages()` 缓存深度冻结的派生消息,每次调用返回新数组。四种 surface 事件类型(`system/message`、`user/message`、`assistant/message`、`tool/result`)提供记录的消息身份和内容,空内容的系统节点不派生消息。插件拥有的投影修改派生内容,不修改记录的消息。替换和投影决策使缓存失效。嵌入式 Assistant stream 与 `assistant/attempt` 事件只保留回放和诊断数据。 +`deriveMessages()` 缓存深度冻结的派生消息,每次调用返回新数组。surface 事件类型(`system/message`、`developer/message`、`user/message`、`assistant/message`、`tool/result`)提供记录的消息身份和内容,空内容的 system 和 developer 节点不派生消息。插件拥有的投影修改派生内容,不修改记录的消息。替换和投影决策使缓存失效。嵌入式 Assistant stream 与 `assistant/attempt` 事件只保留回放和诊断数据。 ### 请求头 @@ -137,7 +139,7 @@ session.deriveMessages() // the derived model history #### 模型看到什么 -模型会接收 `system/message`、`user/message`、`assistant/message` 与 `tool/result` surface 条目中的消息,并应用日志中的投影,系统提示词在先。消息标识、角色、来源及未修改的内容块保持不变,投影不生成标识。直接提示词与注入上下文仍是独立的 `user/message` 事件,各事件的来源保留其出处。嵌入式 stream、`assistant/attempt`、边界与其他仅日志事实不添加消息。 +模型会接收 `system/message`、`developer/message`、`user/message`、`assistant/message` 与 `tool/result` surface 条目中的消息,并应用日志中的投影,系统提示词在先。消息标识、角色、来源及未修改的内容块保持不变,投影不生成标识。直接提示词与注入上下文仍是独立的 `user/message` 事件,各事件的来源保留其出处。嵌入式 stream、`assistant/attempt`、边界与其他仅日志事实不添加消息。 #### Token 影响 @@ -153,6 +155,8 @@ session.deriveMessages() // the derived model history 如果恢复发现 assistant 工具请求没有持久 `tool/call`,其合成 `TOOL_NOT_STARTED` 结果内容为 `The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.`。如果持久 `tool/call` 没有结果,其 `TOOL_OUTCOME_UNKNOWN` 结果内容为 `The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.`。 +Fork 生成的结果只描述继承记录:父会话可能已经在所选事件之后启动或完成调用。`TOOL_NOT_STARTED` 表示前缀中没有启动记录;`TOOL_OUTCOME_UNKNOWN` 表示有启动记录但没有结果。两者都要求模型仅对只读或幂等操作直接重试;有副作用的操作需要先验证外部状态或询问用户。参见 [fork 决策](../../../.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.zh.md)。 + #### Token 影响 未受损会话的 token 增量为零。恢复时,每个修复后的调用都会添加保留的、针对具体风险的错误文本。 @@ -182,8 +186,8 @@ session.deriveMessages() // the derived model history 这些限制说明会话存储何时需要特别留意。它们是当前包约束,不是任务积压。 -- **`fork()` 仅在实时会话的稳定边界处切分**:所选前缀结束时不得有开放轮次,且源会话必须位于存储中;fork API 不支持对已持久化但未加载的会话进行 fork。 -- **`SESSION_FORMAT_VERSION` 命名[当前逻辑表示](../../../docs/session-format-status.zh.md)**——当前读取器拒绝已退役的 `header.system`,并校验 `system/message` 载荷与受保护头节点的重写。历史 header 与事件归相邻格式包所有;相邻迁移链在构造 `Session` 前转换受支持的历史,写打开只发布当前格式的后继代际。同版本未知事件要求信封显式带有 `ignorable` 标记,但这不保证结构迁移的安全性([机制](../../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md))。 +- **Store API 仅接受活跃源会话** — 已持久化但未加载的源会话通过 Host 观察路径处理。Fork 仅闭合开放尾部,不修复先前已闭合步骤中缺失的结果。 +- **`SESSION_FORMAT_VERSION` 命名[当前逻辑表示](../../../docs/session-format-status.zh.md)**——当前读取器拒绝已退役的 `header.system`,并校验 `system/message` 载荷与受保护头节点的重写。历史 header 与事件归相邻格式包所有;[相邻迁移链](../../session/session-format-catalog/README.zh.md)在构造 `Session` 前转换受支持的历史,写打开只发布当前格式的后继代际。同版本未知事件要求信封显式带有 `ignorable` 标记,但这不保证结构迁移的安全性([机制](../../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md))。 - **`TurnEndReasonMap` 不含 ACP(Agent Client Protocol)命名的 `refusal`/`max_turn_requests` 变体**:受生产方约束;只有当适配器或循环首次产生这些变体时才加入。 - **fork 之外没有会话树**:基于分支会话的 pi 风格条目树被推迟,除非消费方需要超越基于边界的 forking 的能力。 diff --git a/packages/core/session/package.json b/packages/core/session/package.json index f0e27221a1..453d4d85cb 100644 --- a/packages/core/session/package.json +++ b/packages/core/session/package.json @@ -26,6 +26,10 @@ "types": "./lib/types/types.d.ts", "default": "./lib/types/types.js" }, + "./fork": { + "types": "./lib/types/fork.d.ts", + "default": "./lib/types/fork.js" + }, "./src/*": "./src/*", "./package.json": "./package.json", "./surface": { diff --git a/packages/core/session/src/fork.ts b/packages/core/session/src/fork.ts new file mode 100644 index 0000000000..8d5b221976 --- /dev/null +++ b/packages/core/session/src/fork.ts @@ -0,0 +1,30 @@ +/** + * Fork seed construction over an exact source-event prefix. + * @module @deepseek-ai/dsh-session/fork + */ + +import { openTurnClosers } from './repair.ts' +import { SessionSeq } from './types.ts' +import type { SessionEvent, SessionSeq as SessionSeqType } from './types.ts' + +/** + * Copy an inclusive event prefix, mark its inherited cut, and close its open tail with forked results + * and step/turn endings. Closed steps and turns are preserved unchanged. + * The caller validates that the boundary is an existing contiguous event seq; + * Session construction snapshots the borrowed events before publication. + * + * @param events - source log with contiguous seqs from zero. + * @param boundary - inclusive source event seq the child inherits through. + * @returns a new array retaining the source event objects, followed by synthetic + * closers outside the inherited prefix counted by `inheritedEventCount`. + */ +export function buildForkSeed(events: readonly SessionEvent[], boundary: SessionSeqType): SessionEvent[] { + const prefix = events.slice(0, boundary + 1) + prefix.push({ + type: 'session/end-seed', seq: SessionSeq(boundary + 1), + // oxlint-disable-next-line typescript/no-non-null-assertion -- the caller validated this exact source event. + time: events[boundary]!.time, + data: { inherited: true }, + }) + return prefix.concat(openTurnClosers(prefix, { kind: 'forked' })) +} diff --git a/packages/core/session/src/index.ts b/packages/core/session/src/index.ts index 548603f613..02922a1739 100644 --- a/packages/core/session/src/index.ts +++ b/packages/core/session/src/index.ts @@ -20,10 +20,13 @@ import { SurfaceManager, validateSessionEventData, validateSurfaceMetadata } fro import type { SessionSurface, SessionMessageProjection } from './surface.ts' import { foldRequestHeader } from './request-header.ts' +import { buildForkSeed } from './fork.ts' + +export { buildForkSeed } from './fork.ts' export * from './types.ts' export { SessionPreparation } from './preparation.ts' export type { SessionPreparationOptions } from './preparation.ts' -export type { AssistantMessage, SystemMessage, ToolResultMessage, UserMessage } from '@deepseek-ai/dsh-llm' +export type { AssistantMessage, DeveloperMessage, SystemMessage, ToolResultMessage, UserMessage } from '@deepseek-ai/dsh-llm' export { interruptedTurnClosers, TOOL_NOT_STARTED, TOOL_OUTCOME_UNKNOWN } from './repair.ts' export type { SessionSurface, SurfaceFoldReplacement, SurfaceFoldResult, SessionMessageProjection, SessionMessageProjectionContext } from './surface.ts' export { deriveEventMessage, foldSurface, isAppendSurfaceEvent, isReplacementSurfaceEvent, isSurfaceEvent, isSurfaceEligibleType } from './surface.ts' @@ -174,6 +177,7 @@ export function adoptSessionEvent(event: T): T { case 'user/message': deepFreeze(event.data) break + case 'developer/message': case 'system/message': case 'assistant/message': case 'tool/result': @@ -228,6 +232,7 @@ function assertSessionEventEnvelope(value: unknown, index: number): asserts valu validateSessionEventData(event as SessionEvent, `seed ${type} at index ${index}`) switch (type) { case 'request/header': + case 'developer/message': case 'system/message': case 'user/message': case 'assistant/attempt': @@ -311,17 +316,18 @@ function assertAdapterDefaults( } } -/** The four surface event types whose payload carries an identified message. */ +/** The surface event types whose payload carries an identified message. */ function isMessageEventType(type: unknown): type is SurfaceEventType { - return type === 'system/message' || type === 'user/message' + return type === 'developer/message' || type === 'system/message' || type === 'user/message' || type === 'assistant/message' || type === 'tool/result' } const MESSAGE_ROLE_BY_TYPE: Record = { 'system/message': 'system', + 'developer/message': 'developer', 'user/message': 'user', 'assistant/message': 'assistant', - 'tool/result': 'user', + 'tool/result': 'tool', } /** Validate only the event-specific invariants needed to safely replay a message. */ @@ -354,9 +360,8 @@ function assertMessageEventShape(event: Record, subject: string } const sourceRecord = source as Record if (type === 'system/message') { - if (sourceRecord['kind'] !== 'plugin' || typeof sourceRecord['plugin'] !== 'string' - || sourceRecord['plugin'] === '') { - throw new Error(`${subject} message must have plugin source`) + if (sourceRecord['kind'] !== 'system-prompt') { + throw new Error(`${subject} message must have system-prompt source`) } return } @@ -372,14 +377,7 @@ function assertMessageEventShape(event: Record, subject: string || sourceRecord['callId'] === '') { throw new Error(`${subject} message must have tool source`) } - const content = messageRecord['content'] as unknown[] - const block = content[0] - if (content.length !== 1 || typeof block !== 'object' || block === null - || (block as Record)['type'] !== 'tool-result' - || !Array.isArray((block as Record)['content'])) { - throw new Error(`${subject} message must contain one tool-result block`) - } - if ((block as Record)['toolCallId'] !== sourceRecord['callId']) { + if (messageRecord['toolCallId'] !== sourceRecord['callId']) { throw new Error(`${subject} message has mismatched tool call ids`) } } @@ -472,30 +470,27 @@ export class Session { } /** - * The first seq appended IN THIS PROCESS: the length of the constructor - * seed (0 without one). Events with smaller seq values entered through - * construction — replay, fork, or resume — and were never published on the - * `session/event` firehose (constructor seeds do not emit). This offset marks - * the constructor-input boundary for lifecycle ownership and persistence - * adoption; consumers that need complete canonical history still start at - * seq 0. Distinct from {@link inheritedEventCount}, the DURABLE - * fork-lineage cut: a resumed session's constructor seed is its full stored - * log, while the inherited count keeps the original fork value — this field is the - * in-process construction fact. + * The constructor seed length (0 without one), before any marker appended + * during construction. Seed events never publish on `session/event`. A + * marker appended before the store attaches occupies this seq without + * publishing either; otherwise this seq is available for the next append. * - * Not persisted itself: a seeded session projects it into the log as the - * `session/end-seed` event, which is what a consumer reading STORED history - * reads. Locate the LAST such event, not necessarily one at this seq — a - * seed already ending in one is not re-marked, so reopening an untouched - * session leaves that event at a smaller seq than `firstLiveSeq`. Prefer - * this field in-process: it is exact before the marker reaches storage. - * - * When this lifecycle appends the marker, it occupies this seq before the - * store attaches and therefore does not publish either. Otherwise this seq - * holds an ordinary published write. + * This in-process offset is not persisted. A fork seed can already contain + * the child's inherited marker and synthetic closers, so its child-owned + * history starts at {@link inheritedEventCount}, before this offset. A + * resumed Session's seed contains its full stored log, while its inherited + * count keeps the durable fork cut. Consumers needing complete canonical + * history start at seq 0. */ readonly firstLiveSeq: SessionLogOffset + /** + * First event produced for this object lifecycle. A new fork includes its + * child-owned seed marker and closers; a restored Session starts after its + * complete stored prefix. This in-process capture offset is not persisted. + */ + readonly firstLifecycleSeq: SessionLogOffset + /** * Create a detached session by validating and snapshotting borrowed seed * events and storage metadata. @@ -605,16 +600,22 @@ export class Session { if (inheritedEventCount > this.log.length) { throw new Error('session inherited event count exceeds its event log') } - if (mode === 'snapshot' && this.header.isSeeded && inheritedEventCount !== this.log.length) { - throw new Error('seeded session constructor seed must equal its inherited prefix') + const seedMarker = this.log[inheritedEventCount] + const markedSeed = seedMarker?.type === 'session/end-seed' && seedMarker.data.inherited === true + if (mode === 'snapshot' && this.header.isSeeded && inheritedEventCount !== this.log.length && !markedSeed) { + throw new Error('seeded session constructor seed must equal its inherited prefix or mark its inherited cut') + } + if (markedSeed && this.log.slice(inheritedEventCount + 1).some(event => event.type === 'session/end-seed' && event.data.inherited === true)) { + throw new Error('session inherited event count must identify the final inherited marker') } this.inheritedEventCount = inheritedEventCount + this.firstLifecycleSeq = mode === 'snapshot' && this.header.isSeeded ? inheritedEventCount : this.firstLiveSeq // A fresh seeded child always owns one tagged marker at its inherited cut, // even when the copied prefix already ends in an ancestor marker. Restore // retains that durable marker and appends only the ordinary resume marker. - if (seed !== undefined && mode === 'snapshot' && this.header.isSeeded) { + if (seed !== undefined && mode === 'snapshot' && this.header.isSeeded && !markedSeed) { this.append('session/end-seed', { inherited: true }) - } else if (seed !== undefined && this.log.at(-1)?.type !== 'session/end-seed') { + } else if (seed !== undefined && !(mode === 'snapshot' && this.header.isSeeded) && this.log.at(-1)?.type !== 'session/end-seed') { this.append('session/end-seed', {}) } } @@ -879,16 +880,14 @@ export type SessionForkSource = Session | SessionId * Rejection codes for session forking: the fork source id is unknown to the * live store (`SESSION_NOT_FOUND`) or names a session object that is not the * store's live instance (`SESSION_NOT_LIVE`); the requested child id is - * already taken (`SESSION_ALREADY_EXISTS`); the boundary is not a contiguous - * existing seq (`INVALID_BOUNDARY`); or the selected prefix ends inside an - * open turn (`OPEN_TURN`). + * already taken (`SESSION_ALREADY_EXISTS`); or the boundary is not a contiguous + * existing seq (`INVALID_BOUNDARY`). */ export type SessionForkErrorCode = | 'SESSION_NOT_FOUND' | 'SESSION_NOT_LIVE' | 'SESSION_ALREADY_EXISTS' | 'INVALID_BOUNDARY' - | 'OPEN_TURN' /** Typed error for session fork rejections. */ export class SessionForkError extends Error { @@ -1220,10 +1219,12 @@ export class SessionStore extends Service { } /** - * Create a live child session from a stable prefix of a live source. + * Create a live child session from an exact prefix of a live source. * `boundary` is an inclusive source event seq; omitted means the source's - * current last event. The selected slice may end with a between-turn event - * but must not end inside an open turn. + * current last event. An open tail receives synthetic tool results and + * step/turn closers with the forked cause. Closed steps and turns remain + * unchanged, including any failed tool calls already missing results. + * `inheritedEventCount` counts only copied source events, excluding these closers. * * @param source - Live source session object or id. * @param boundary - Inclusive source event seq to fork through; omitted means @@ -1238,10 +1239,13 @@ export class SessionStore extends Service { throw new SessionForkError(`session "${childSessionId}" already exists`, 'SESSION_ALREADY_EXISTS') } const liveSource = this._resolveForkSource(source) - const seed = this._forkSeed(liveSource, boundary) + // oxlint-disable-next-line typescript/no-deprecated -- Existing fork snapshot read; migration deferred. + const events = liveSource.snapshotEvents() + const resolved = this._forkBoundary(liveSource.id, events, boundary) + const seed = resolved === undefined ? [] : buildForkSeed(events, resolved) return this.create(childSessionId, { seed, - inheritedEventCount: SessionLogOffset(seed.length), + inheritedEventCount: SessionLogOffset(resolved === undefined ? 0 : resolved + 1), meta: { ...liveSource.header.cwd !== undefined ? { cwd: liveSource.header.cwd } : {}, parentSession: liveSource.id, @@ -1250,50 +1254,39 @@ export class SessionStore extends Service { }) } - private _forkSeed(session: Session, requestedBoundary: SessionSeq | undefined): readonly SessionEvent[] { - // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred. - const lastEvent = session.snapshotEvents().at(-1) + private _forkBoundary( + sessionId: SessionId, events: readonly SessionEvent[], requestedBoundary: SessionSeq | undefined, + ): SessionSeq | undefined { + const lastEvent = events.at(-1) let boundary: SessionSeq if (requestedBoundary !== undefined) { boundary = requestedBoundary } else { - if (lastEvent === undefined) return [] + if (lastEvent === undefined) return undefined boundary = lastEvent.seq } if (!Number.isSafeInteger(boundary) || boundary < 0) { throw new SessionForkError( - `fork boundary for session "${session.id}" must be a non-negative safe integer, got ${String(boundary)}`, + `fork boundary for session "${sessionId}" must be a non-negative safe integer, got ${String(boundary)}`, 'INVALID_BOUNDARY', ) } - if (boundary >= session.seq) { + if (boundary >= events.length) { const lastSeq = lastEvent?.seq throw new SessionForkError( - `fork boundary ${boundary} does not exist in session "${session.id}" (last seq: ${lastSeq ?? 'none'})`, + `fork boundary ${boundary} does not exist in session "${sessionId}" (last seq: ${lastSeq ?? 'none'})`, 'INVALID_BOUNDARY', ) } - // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred. - const boundaryEvent = session.eventAt(boundary) + const boundaryEvent = events[boundary] if (boundaryEvent === undefined || boundaryEvent.seq !== boundary) { throw new SessionForkError( - `fork boundary ${boundary} does not match a contiguous event seq in session "${session.id}"`, + `fork boundary ${boundary} does not match a contiguous event seq in session "${sessionId}"`, 'INVALID_BOUNDARY', ) } - // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred. - const events = session.snapshotEvents(SessionLogOffset(0), SessionLogOffset(boundary + 1)) - const lastTurnBoundary = events - .findLast(event => event.type === 'turn/start' || event.type === 'turn/end') - if (lastTurnBoundary?.type === 'turn/start') { - throw new SessionForkError( - `fork boundary ${boundary} in session "${session.id}" ends inside open turn ${lastTurnBoundary.data.turn}`, - 'OPEN_TURN', - ) - } - - return events + return boundary } private _resolveForkSource(source: SessionForkSource): Session { diff --git a/packages/core/session/src/invariant.ts b/packages/core/session/src/invariant.ts index be4b214c86..154c953438 100644 --- a/packages/core/session/src/invariant.ts +++ b/packages/core/session/src/invariant.ts @@ -104,6 +104,10 @@ function validateEvent( openStep = event.data.step break } + case 'developer/message': { + requireOpenStep(trace, 'developer/message', event.data.turn, event.data.step, fail) + break + } case 'step/end': { requireOpenStep(trace, 'step/end', event.data.turn, event.data.step, fail) pendingCalls = { kind: 'clear' } @@ -135,7 +139,7 @@ function validateEvent( } requireOpenStep(trace, 'tool/result', event.data.turn, event.data.step, fail) const callId = event.data.message.source.callId - const syntheticNotStarted = event.data.message.content[0].isError === true && event.data.error?.code === TOOL_NOT_STARTED + const syntheticNotStarted = event.data.message.isError === true && event.data.error?.code === TOOL_NOT_STARTED if (!trace.pendingCalls.has(callId) && !syntheticNotStarted) { fail(`tool/result for ${callId} with no prior tool/call in this step`) } diff --git a/packages/core/session/src/known-event-types.ts b/packages/core/session/src/known-event-types.ts index 49ced22dce..adaca29255 100644 --- a/packages/core/session/src/known-event-types.ts +++ b/packages/core/session/src/known-event-types.ts @@ -34,6 +34,7 @@ export const KNOWN_SESSION_EVENT_TYPES: ReadonlySet = new Set([ 'compaction/start', 'compaction/summary', 'deliverables/presented', + 'developer/message', 'feedback/message-delete', 'feedback/message-put', 'feedback/record', diff --git a/packages/core/session/src/repair.ts b/packages/core/session/src/repair.ts index e78187df6f..b87a69c351 100644 --- a/packages/core/session/src/repair.ts +++ b/packages/core/session/src/repair.ts @@ -1,7 +1,10 @@ /** - * Crash-recovery repair for an interrupted session log. It preserves a fully - * written final turn and supplies the missing tool, step, and turn boundaries - * needed to resume with a provider-valid transcript. + * Synthetic closer events that balance a session log whose tail turn is open. + * Two producers share the mechanism: crash recovery closes an interrupted + * persisted log on reload, and fork-seed construction closes a prefix cut + * inside the source's open turn. Both preserve every fully written event and + * close the unfinished step and turn. Calls in already closed steps remain + * unchanged, including any missing results. * @module @deepseek-ai/dsh-session/repair */ @@ -17,16 +20,47 @@ export const TOOL_NOT_STARTED = 'TOOL_NOT_STARTED' /** Recovery code for a recorded tool call whose completed outcome was not durably recorded. */ export const TOOL_OUTCOME_UNKNOWN = 'TOOL_OUTCOME_UNKNOWN' +/** + * Why an open tail turn is closed with synthetic events: `interrupted` is + * crash recovery over a persisted log; `forked` is a fork seed cut inside the + * source's open turn. The cause selects the synthetic `turn/end` reason, the + * model-visible wording of synthetic error tool results, and the + * deterministic synthetic message-id prefix. The error codes + * ({@link TOOL_NOT_STARTED} / {@link TOOL_OUTCOME_UNKNOWN}) are shared: both + * causes state the same fact about the call's recorded lifecycle. + */ +export type OpenTurnCloseCause = { readonly kind: 'interrupted' } | { readonly kind: 'forked' } + +/** Model-visible wording of the synthetic error tool results, keyed by cause. */ +const CLOSER_TEXT = { + interrupted: { + started: 'The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.', + notStarted: 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.', + }, + forked: { + started: 'The history inherited by this branch records this tool call starting but does not include its result. The parent session may have completed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.', + notStarted: 'The history inherited by this branch has no record of this tool call starting. The parent session may have executed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.', + }, +} as const + /** * Return deterministic synthetic events that close an open tail turn. Unmatched - * calls receive error results first, followed by an open `step/end` and an - * interrupted `turn/end`; sequences continue the log and timestamps reuse the - * last real event. A balanced or empty log returns no events. + * calls in its open step receive error results, followed by `step/end` and a + * `turn/end` carrying the cause's reason. Calls in closed steps remain unchanged. + * Sequences continue the log and timestamps reuse the last real event. A balanced or empty log returns no + * events. * - * @param events - the loaded durable log to scan (a valid committed prefix, possibly with a crash tail). + * Package-internal: each cause has exactly one owner, so external callers go + * through {@link interruptedTurnClosers} (persistence crash recovery) or + * `buildForkSeed` in `./fork.ts` (fork seeds) instead of selecting a cause. + * + * @param events - the log to scan: a valid committed prefix, possibly ending + * inside an open turn (a crash tail or a mid-turn fork cut). + * @param cause - why the turn is being closed; selects the `turn/end` reason + * and the model-visible wording of synthetic error tool results. * @returns the synthetic closer events to append after `events`, in order; empty when the log is already balanced. */ -export function interruptedTurnClosers(events: readonly SessionEvent[]): SessionEvent[] { +export function openTurnClosers(events: readonly SessionEvent[], cause: OpenTurnCloseCause): SessionEvent[] { let openTurn: number | null = null let openStep: number | null = null // Reset at each turn boundary so earlier calls cannot leak into tail repair. @@ -76,7 +110,7 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session } } - // Balanced log (no crash mid-turn): nothing to close. An open turn implies + // Balanced log (no open tail turn): nothing to close. An open turn implies // `events` is non-empty (its turn/start was logged), so `last` exists. const last = events.at(-1) if (openTurn === null || last === undefined) return [] @@ -88,24 +122,19 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session const time = last.time const closers: SessionEvent[] = [] - // Close calls before their step: providers reject dangling assistant calls, - // and Map insertion order preserves their transcript order. + // Close calls before their step; Map insertion order preserves transcript order. + const text = CLOSER_TEXT[cause.kind] for (const [callId, { step, callSeq }] of pendingCalls) { const started = callSeq !== undefined const message: ToolResultMessage = deepFreeze({ - id: brandString(`interrupted-tool-result-${callId}-${seq}`), - role: 'user', + id: brandString(`${cause.kind}-tool-result-${callId}-${seq}`), + role: 'tool', + toolCallId: callId, + isError: true, source: { kind: 'tool', callId }, content: [{ - type: 'tool-result', - toolCallId: callId, - isError: true, - content: [{ - type: 'text', - text: started - ? 'The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.' - : 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.', - }], + type: 'text', + text: started ? text.started : text.notStarted, }], }) closers.push({ @@ -130,6 +159,19 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session if (openStep !== null) { closers.push({ type: 'step/end', seq: SessionSeq(seq++), time, data: { turn: openTurn, step: openStep } }) } - closers.push({ type: 'turn/end', seq: SessionSeq(seq++), time, data: { turn: openTurn, reason: { kind: 'interrupted' } } }) + closers.push({ type: 'turn/end', seq: SessionSeq(seq++), time, data: { turn: openTurn, reason: { kind: cause.kind } } }) return closers } + +/** + * Crash-recovery entry point: synthetic closers that balance a persisted log + * whose tail turn was interrupted. Used by crash-recovery callers; fork + * seeds receive their `forked`-cause closers through `buildForkSeed` in + * `./fork.ts`, and cause selection stays internal to those two owners. + * + * @param events - the persisted log to scan, possibly ending inside an open turn. + * @returns the synthetic `interrupted` closer events to append after `events`; empty when the log is already balanced. + */ +export function interruptedTurnClosers(events: readonly SessionEvent[]): SessionEvent[] { + return openTurnClosers(events, { kind: 'interrupted' }) +} diff --git a/packages/core/session/src/surface.ts b/packages/core/session/src/surface.ts index 9bc3d32a8c..eeedca77b9 100644 --- a/packages/core/session/src/surface.ts +++ b/packages/core/session/src/surface.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-session/surface */ -import type { Message } from '@deepseek-ai/dsh-llm' +import type { Message, ToolSchema } from '@deepseek-ai/dsh-llm' import { SessionLogOffset, SessionSeq } from './types.ts' import { KNOWN_SESSION_EVENT_TYPES, MESSAGE_PROJECTION_EVENT_TYPES } from './known-event-types.ts' import type { @@ -49,6 +49,7 @@ export interface SessionMessageProjection([ 'system/message', + 'developer/message', 'user/message', 'assistant/message', 'tool/result', @@ -57,7 +58,7 @@ const SURFACE_EVENT_TYPES = new Set([ /** * Whether an event type can join the model-visible surface. * @param type - event type to test. - * @returns true for one of the four message-producing event types. + * @returns true for one of the message-producing event types. */ export function isSurfaceEligibleType(type: string): boolean { return SURFACE_EVENT_TYPES.has(type) @@ -107,7 +108,7 @@ export function isReplacementSurfaceEvent( /** * Project a single event into the LLM message it derives to, or null when it * produces none — a non-surface event (attempt, boundary, log-only record) or an - * empty-content assistant/message (which exists only to host usage). A caller + * empty-content system, developer, or assistant message. A caller * reconstructing model input supplies the same prefix's `projectedMessages` * from {@link foldSurface}; without that map this function reads original * event content. Session instance methods apply the live projection. Messages @@ -137,12 +138,11 @@ export function deriveEventMessage( case 'user/message': { return event.data } - // An empty-content message projects to no wire message. For - // system/message the node records "no system prompt" while keeping its - // surface position; for assistant/message the event exists only to host a - // max-tokens step's usage and must not inject a content-less assistant - // turn into the provider transcript. + // Empty system and developer nodes retain their surface positions without + // adding wire messages. An empty assistant event hosts a max-tokens step's + // usage and must not inject a content-less turn into the provider transcript. case 'system/message': + case 'developer/message': case 'assistant/message': { if (event.data.message.content.length === 0) return null return event.data.message @@ -163,17 +163,46 @@ function isRecord(value: unknown): value is Record { } /** - * Reject noncanonical request-header fields and contradictory tool failure metadata. + * Reject noncanonical request-header fields, developer roles/content, and contradictory tool failure metadata. * This does not validate complete event payloads or embedded provider streams. * @param event - event whose locally related payload fields are inspected. * @param subject - event location to include in validation errors. - * @throws when request data/header is not an object, optional header fields are empty, or tool failure metadata contradicts its message. + * @throws when request-header fields, developer roles/content, or tool failure metadata are invalid. */ export function validateSessionEventData( event: Pick, subject: string, ): void { const data: unknown = event.data + if (SURFACE_EVENT_TYPES.has(event.type) && isRecord(data)) { + const message = event.type === 'user/message' ? data : data['message'] + if (isRecord(message)) { + if ((event.type === 'developer/message') !== (message['role'] === 'developer')) { + throw new Error(`${subject} developer/message and developer role must occur together`) + } + if (message['role'] !== 'developer' && Array.isArray(message['content']) + && message['content'].some((block: unknown) => isRecord(block) + && (block['type'] === 'tool-addition' || block['type'] === 'tool-removal'))) { + throw new Error(`${subject} tool-change blocks require developer role`) + } + if (event.type === 'developer/message' && Array.isArray(message['content'])) { + let hasAdditions = false + for (const block of message['content']) { + if (!isRecord(block) || (block['type'] !== 'tool-addition' && block['type'] !== 'tool-removal')) continue + if (typeof block['toolName'] !== 'string' || block['toolName'].length === 0) { + throw new Error(`${subject} ${block['type']} requires a nonempty toolName`) + } + if (block['type'] === 'tool-addition') { + hasAdditions = true + if (Object.hasOwn(block, 'tool')) throw new Error(`${subject} tool-addition must omit inline tool definitions`) + } + } + if (hasAdditions ? !isEventSeq(data['headerSeq']) : Object.hasOwn(data, 'headerSeq')) { + throw new Error(`${subject} requires headerSeq exactly when tool additions are present`) + } + } + } + } if (event.type === 'request/header') { if (!isRecord(data)) throw new Error(`${subject} data must be an object`) const header = data['header'] @@ -190,10 +219,8 @@ export function validateSessionEventData( if (!isRecord(data)) throw new Error(`${subject} data must be an object`) if (data['error'] === undefined) return const message = data['message'] - const content = isRecord(message) ? message['content'] : undefined - const block: unknown = Array.isArray(content) ? content[0] : undefined - if (!isRecord(block) || block['isError'] !== true) { - throw new Error(`${subject} error requires message content[0].isError === true`) + if (!isRecord(message) || message['isError'] !== true) { + throw new Error(`${subject} error requires message.isError === true`) } } } @@ -343,6 +370,36 @@ function assertSourceEventReferences( } } +/** Resolve tool additions against their immutable historical request header. */ +function assertDeveloperHeader( + event: SessionEvent, + events: readonly SessionEvent[], + baseSeq: SessionLogOffset, +): void { + if (event.type !== 'developer/message') return + validateSessionEventData(event, `developer/message at seq ${event.seq}`) + if (event.data.headerSeq === undefined) return + const headerSeq = event.data.headerSeq + const headerEvent = events[headerSeq - baseSeq] + if (headerSeq >= event.seq || headerEvent?.type !== 'request/header') { + throw new Error('developer/message headerSeq must reference an earlier request/header') + } + for (const block of event.data.message.content) { + if (block.type !== 'tool-addition') continue + const definitions = headerEvent.data.header.tools?.filter(tool => tool.name === block.toolName) ?? [] + if (definitions.length !== 1) { + throw new Error(`developer/message tool-addition "${block.toolName}" must name exactly one tool in headerSeq ${headerSeq}`) + } + const definition = definitions[0] as ToolSchema + if (typeof definition.description !== 'string' || !isRecord(definition.parameters)) { + throw new Error(`developer/message tool-addition "${block.toolName}" requires a complete tool definition in headerSeq ${headerSeq}`) + } + if (Object.hasOwn(definition, 'deferLoading') && definition.deferLoading !== true) { + throw new Error('developer/message referenced tool deferLoading must be true when present') + } + } +} + /** * Validate one event's surface metadata without checking membership in a log or surface. * @param event - event whose marker and source sequence values are inspected. @@ -419,15 +476,13 @@ function assertToolResultRewrite( } const originalRest = { ...original.data } as Record const replacementRest = { ...event.data } as Record - const originalResult = original.data.message.content[0] - const replacementResult = event.data.message.content[0] originalRest['message'] = { ...original.data.message, - content: [{ ...originalResult, content: null }], + content: null, } replacementRest['message'] = { ...event.data.message, - content: [{ ...replacementResult, content: null }], + content: null, } if (!isDeepEqualJson(originalRest, replacementRest)) { throw new Error('tool/result surface replacement may change only content') @@ -470,6 +525,7 @@ function planSurfaceEvent( throw new Error(`session event seq ${event.seq} is not contiguous; expected ${expectedSeq}`) } const surfaceOp = validateSurfaceMetadata(event) + assertDeveloperHeader(event, events, baseSeq) const projection = projections.find(item => item.type === event.type) if (projection !== undefined) { return { kind: 'project', projection, messages: projection.project(event, { diff --git a/packages/core/session/src/types.ts b/packages/core/session/src/types.ts index 0b946bd17a..e929ad3c4c 100644 --- a/packages/core/session/src/types.ts +++ b/packages/core/session/src/types.ts @@ -1,6 +1,7 @@ import { brandNumber, brandString, type Branded, type BrandedNumber } from '@deepseek-ai/dsh-brand' import type { AssistantMessage, + DeveloperMessage, AssistantStreamRecord, ToolCallId, LlmCallConfig, @@ -85,7 +86,7 @@ export type OptionalSessionSeq = SessionSeq | null * immutable prior-generation, and current fast-path rules are recorded in * `.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md`. */ -export const SESSION_FORMAT_VERSION = 3 +export const SESSION_FORMAT_VERSION = 4 /** * Immutable validated storage metadata, kept outside the conversation event log. @@ -139,8 +140,8 @@ export interface CreateSessionOptions { readonly seed?: readonly SessionEvent[] /** * Exact fork-inherited prefix length when `meta.isSeeded` is true. The - * constructor seed is exactly this inherited prefix; the constructor - * appends the child-owned tagged marker at the cut. + * constructor appends the child-owned tagged marker at the cut unless + * the seed already includes it followed by child-owned fork closers. */ readonly inheritedEventCount?: SessionLogOffset /** @@ -218,6 +219,13 @@ export interface TurnEndReasonMap { * the events recorded before the crash remain intact. */ interrupted: { kind: 'interrupted' } + /** + * Fork-seed construction closed a turn that was still open at the fork + * boundary in the source session. Only fork seeds carry this marker — the + * loop never emits it — and the source events before the boundary remain + * intact in the child. + */ + forked: { kind: 'forked' } } /** The union over {@link TurnEndReasonMap} — why a turn ended; plugins extend it by merging variants into the map. */ @@ -236,6 +244,10 @@ export interface EpochHeader { adapterDefaults?: LlmCallConfigAdapterDefaults /** Assembled tool schemas; absent for a tool-less request. */ tools?: ToolSchema[] + /** Retired request text; system prompts belong to system/message events. + * @persistenceReserved + */ + system?: never } /** Registration-bound metadata for one resolved model route. */ @@ -295,6 +307,14 @@ export interface SessionEventMap { * project their `content` verbatim; `source` tells them apart. */ 'user/message': UserMessage + /** An incremental agent session change admitted at the named turn and step. */ + 'developer/message': { + turn: number + step: number + message: DeveloperMessage + /** Earlier request/header defining every tool addition; required exactly when additions are present. */ + headerSeq?: SessionSeq + } /** * The rendered system prompt on the model-visible surface. The loop appends * the first one as surface node 0 before the step's first `user/message`. @@ -358,7 +378,7 @@ export interface SessionEventMap { message: ToolResultMessage /** * Optional failure identity and raw user-facing reason, outside model content; - * allowed only when the tool-result block has `isError: true`. + * allowed only when the message has `isError: true`. */ error?: { name: string; code: string; reason?: string } meta?: JsonValue @@ -381,19 +401,21 @@ export interface SessionEventMap { */ 'request/context': RequestContext /** - * Marks the end of a constructor seed. Events before it have smaller seq - * values and came from the seed (resume, fork, or replay); this lifecycle - * produced none of them. This log-only event is the durable projection of - * {@link Session.firstLiveSeq}. + * Separates inherited or restored history from later lifecycle-owned work. + * This log-only marker need not be at {@link Session.firstLiveSeq}: a fork + * seed can already contain its tagged marker and child-owned synthetic + * closers before construction. * * A fresh fork child owns one `{ inherited: true }` marker at its exact * inherited-prefix cut, even when that prefix ends in an ancestor marker. - * The last tagged marker is the current Session's cut; untagged markers keep - * ordinary restore and replay lifecycle boundaries. + * `buildForkSeed` appends that marker before any synthetic closers; the + * `Session` constructor supplies it when given only the inherited prefix. + * The last tagged marker is the current Session's cut; untagged markers + * keep ordinary restore and replay lifecycle boundaries. * - * `Session`'s constructor is the only legitimate writer. The invariant - * companion deliberately constrains nothing here, so a plugin appending one - * would silently classify every live bracket before it as seed history. + * Only the `Session` constructor and `buildForkSeed` may create this marker. + * The invariant companion deliberately constrains nothing here, so a plugin + * appending one would silently classify every live bracket before it as seed history. * * An owner of a standalone open/close bracket (`compaction/start` … * `compaction/end`) reads it because seed history and live work are otherwise @@ -416,6 +438,7 @@ export type SessionEventType = keyof SessionEventMap */ export type SurfaceEventType = | 'system/message' + | 'developer/message' | 'user/message' | 'assistant/message' | 'tool/result' diff --git a/packages/core/session/tests/canonical-envelopes.spec.ts b/packages/core/session/tests/canonical-envelopes.spec.ts index ec78041a8b..1c52750edb 100644 --- a/packages/core/session/tests/canonical-envelopes.spec.ts +++ b/packages/core/session/tests/canonical-envelopes.spec.ts @@ -72,7 +72,7 @@ const invalidData = [ rule: /must omit header.system/, })), { name: 'successful tool has failure metadata', event: toolEvent({ ...toolData(false), error: failure }), rule: /error requires/ }, - ...[undefined, null, [], {}, { content: null }, { content: [] }, { content: [null] }, { content: [{ isError: 'true' }] }].map(message => ({ + ...[undefined, null, [], {}, { isError: 'true' }, { content: [{ isError: true }] }].map(message => ({ name: 'malformed tool message with failure metadata', event: toolEvent({ turn: 1, step: 1, ...message === undefined ? {} : { message }, error: failure }), rule: /error requires/, @@ -80,6 +80,21 @@ const invalidData = [ ] describe('canonical event payload acceptance', () => { + it('restores system prompts only with system-prompt producer attribution', () => { + const message = createSystemMessage('prompt') + const event: SessionEvent<'system/message'> = { + type: 'system/message', seq: SessionSeq(0), time: 1, surfaceOp: 'append', + data: { turn: 1, step: 1, message }, + } + for (const accept of [entryPaths.seed!, entryPaths.restore!, entryPaths.adopt!, entryPaths.snapshot!]) { + expect(() => accept(structuredClone(event))).not.toThrow() + for (const source of [{ kind: 'runtime-context' }, { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, { kind: 'user' }]) { + const invalid = { ...event, data: { ...event.data, message: { ...message, source } } } + expect(() => accept(invalid as unknown as SessionEvent)).toThrow(/system-prompt source/) + } + } + }) + for (const [path, accept] of Object.entries(entryPaths)) { describe(path, () => { it.each(invalidData)('rejects $name with a located error', ({ event, rule }) => { @@ -107,7 +122,7 @@ describe('canonical event payload acceptance', () => { } it('preserves nested header, source, and data extras without normalizing accepted events', () => { - const message = createSystemMessage('prompt', 'fixture') + const message = createSystemMessage('prompt') const events: SessionEvent[] = [ requestEvent({ header: { config, extra: { nested: [true, null] } }, reason: 'initial', extra: ['retained'] }), { type: 'system/message', seq: SessionSeq(0), time: 1, surfaceOp: 'append', data: { @@ -295,9 +310,9 @@ describe('canonical event-local surface metadata', () => { it('requires system placement and preserves system data and source-event references on head replacements', () => { const session = Session.create(id) - const data = { turn: 1, step: 1, message: createSystemMessage('head', 'fixture'), extra: { nested: true } } + const data = { turn: 1, step: 1, message: createSystemMessage('head'), extra: { nested: true } } const head = session.append('system/message', data, { surfaceOp: 'append' }) - const next = session.append('system/message', { ...data, message: createSystemMessage('next', 'fixture') }, { + const next = session.append('system/message', { ...data, message: createSystemMessage('next') }, { surfaceOp: { op: 'replace', startSeq: head.seq, endSeq: head.seq }, sourceEventSeqs: [head.seq], }) expect(next.data).toEqual({ ...data, message: next.data.message }) diff --git a/packages/core/session/tests/derived-cache.spec.ts b/packages/core/session/tests/derived-cache.spec.ts index 21d2b7153b..d37ea4e190 100644 --- a/packages/core/session/tests/derived-cache.spec.ts +++ b/packages/core/session/tests/derived-cache.spec.ts @@ -1,4 +1,5 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' +import type { MessageSource } from '@deepseek-ai/dsh-llm' /** * Derived-message cache contract against a scratch oracle: project new nodes * once, rebuild on surface replacements, return fresh arrays over shared @@ -8,6 +9,13 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' import { Session, SessionId } from '@deepseek-ai/dsh-session' +type CheckpointSource = Extract + +/** Build a typed checkpoint source for a derived-message fixture. */ +function checkpointSource(compactionId: string): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: compactionId as CheckpointSource['compactionId'] } +} + function userText(session: Session, text: string): void { session.append('user/message', createUserMessage({ content: [{ type: 'text', text }], source: { kind: 'user' }, @@ -65,7 +73,7 @@ describe('derived-message cache', () => { const nodes = session.surface.nodes session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'summary' }], source: { kind: 'plugin', plugin: 'compact' }, + content: [{ type: 'text', text: 'summary' }], source: checkpointSource('derived-cache-compaction'), }), { surfaceOp: { op: 'replace', startSeq: nodes[0]!, endSeq: nodes[1]! }, sourceEventSeqs: [nodes[0]!, nodes[1]!] }) expect(session.deriveMessages()).toHaveLength(1) diff --git a/packages/core/session/tests/developer-header.spec.ts b/packages/core/session/tests/developer-header.spec.ts new file mode 100644 index 0000000000..de38469c8e --- /dev/null +++ b/packages/core/session/tests/developer-header.spec.ts @@ -0,0 +1,109 @@ +/** Tool additions bind to one historical request header across Session lifecycle paths. */ +import { describe, expect, it } from 'vitest' +import { createDeveloperMessage } from '@deepseek-ai/dsh-llm' +import type { ToolSchema } from '@deepseek-ai/dsh-llm' +import { Session, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' +import type { SessionEvent } from '@deepseek-ai/dsh-session' +import { buildForkSeed } from '@deepseek-ai/dsh-session/fork' +import { foldSurface } from '../src/surface.ts' + +const first: ToolSchema = { name: 'search', description: 'First', parameters: { type: 'object' } } +const second: ToolSchema = { name: 'search', description: 'Second', parameters: { properties: { query: { type: 'string' } } } } +const addition = () => createDeveloperMessage({ source: { kind: 'test' }, content: [{ type: 'tool-addition', toolName: 'search' }] }) + +function opened(tools: ToolSchema[] = [first]) { + const session = Session.create(SessionId('developer-header')) + session.append('turn/start', { turn: 1 }) + session.append('step/start', { turn: 1, step: 1 }) + const headerSeq = session.append('request/header', { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools } }).seq + return { session, headerSeq } +} + +describe('developer request-header references', () => { + it('keeps an older header binding through compound changes, replacement, restore, and fork', () => { + const { session, headerSeq } = opened([first, { name: 'other', description: 'Other', parameters: {} }]) + session.append('request/header', { reason: 'change', header: { config: { provider: 'test', model: 'test' }, tools: [second] } }) + const message = createDeveloperMessage({ source: { kind: 'test' }, content: [ + { type: 'tool-removal', toolName: 'search' }, + { type: 'tool-addition', toolName: 'search' }, + { type: 'tool-addition', toolName: 'other' }, + ] }) + const initial = session.append('developer/message', { turn: 1, step: 1, headerSeq, message }, { surfaceOp: 'append' }) + const replacement = session.append('developer/message', { turn: 1, step: 1, headerSeq, message: addition() }, { + surfaceOp: { op: 'replace', startSeq: initial.seq, endSeq: initial.seq }, sourceEventSeqs: [initial.seq], + }) + const events = session.snapshotEvents() + expect(events[headerSeq]).toMatchObject({ data: { header: { tools: [first, { name: 'other', description: 'Other', parameters: {} }] } } }) + expect(replacement.data.message.content).toEqual([{ type: 'tool-addition', toolName: 'search' }]) + expect(foldSurface(events).nodes).toEqual([replacement.seq]) + const restored = Session.fromRestore(session.id, events, session.header, SessionLogOffset(0), 'shared-frozen') + expect(restored.deriveMessages()).toEqual([replacement.data.message]) + const childId = SessionId('developer-header-child') + const child = Session.create(childId, buildForkSeed(events, replacement.seq), { + ...session.header, id: childId, parentSession: session.id, isSeeded: true, + }, SessionLogOffset(replacement.seq + 1)) + expect(child.snapshotEvents()[replacement.seq]).toEqual(replacement) + expect(child.snapshotEvents()[headerSeq]).toEqual(events[headerSeq]) + }) + + it.each([0, 3, 100])('refuses a non-header or non-earlier reference %s before append', (reference) => { + const { session } = opened() + const before = session.snapshotEvents() + expect(() => session.append('developer/message', { + turn: 1, step: 1, headerSeq: SessionSeq(reference), message: addition(), + }, { surfaceOp: 'append' })).toThrow('earlier request/header') + expect(session.snapshotEvents()).toBe(before) + }) + + it.each([{ tools: [{ ...first, name: 'different' }] }, { tools: [first, second] }])('refuses missing or ambiguous historical tool names %#', ({ tools }) => { + const { session, headerSeq } = opened(tools) + expect(() => session.append('developer/message', { turn: 1, step: 1, headerSeq, message: addition() }, { surfaceOp: 'append' })) + .toThrow('exactly one tool') + }) + + it('refuses an addition bound to a tool-less header', () => { + const session = Session.create(SessionId('without-tools')) + const headerSeq = session.append('request/header', { reason: 'initial', header: { config: { provider: 'test', model: 'test' } } }).seq + expect(() => session.append('developer/message', { turn: 1, step: 1, headerSeq, message: addition() }, { surfaceOp: 'append' })) + .toThrow('exactly one tool') + }) + + it('requires a header exactly for additions and rejects inline definitions', () => { + const { session, headerSeq } = opened() + expect(() => session.append('developer/message', { turn: 1, step: 1, message: addition() }, { surfaceOp: 'append' })).toThrow('requires headerSeq') + const removal = createDeveloperMessage({ source: { kind: 'test' }, content: [{ type: 'tool-removal', toolName: 'search' }] }) + expect(() => session.append('developer/message', { turn: 1, step: 1, headerSeq, message: removal }, { surfaceOp: 'append' })).toThrow('requires headerSeq') + // @ts-expect-error -- legacy inline definitions are rejected at Session admission. + const inline = createDeveloperMessage({ source: { kind: 'test' }, content: [{ type: 'tool-addition', toolName: 'search', tool: first }] }) + expect(() => session.append('developer/message', { turn: 1, step: 1, headerSeq, message: inline }, { surfaceOp: 'append' })).toThrow('omit inline') + const unnamed = createDeveloperMessage({ source: { kind: 'test' }, content: [{ type: 'tool-addition', toolName: '' }] }) + expect(() => session.append('developer/message', { turn: 1, step: 1, headerSeq, message: unnamed }, { surfaceOp: 'append' })).toThrow('nonempty toolName') + }) + + it.each([ + { name: 'search' }, + { name: 'search', description: null, parameters: {} }, + { name: 'search', description: '', parameters: [] }, + { name: 'search', description: '', parameters: {}, deferLoading: false }, + ])('refuses an incomplete referenced definition in imported history %#', (tool) => { + const { session, headerSeq } = opened() + const source = session.snapshotEvents()[headerSeq]! + const events = JSON.parse(JSON.stringify([ + ...session.snapshotEvents().slice(0, headerSeq), + { ...source, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [tool] } } }, + { type: 'developer/message', seq: 3, time: 4, surfaceOp: 'append', data: { turn: 1, step: 1, headerSeq, message: addition() } }, + ])) as SessionEvent[] + expect(() => Session.create(SessionId('incomplete-tool'), events)).toThrow(/complete tool definition|deferLoading/) + }) + + it('applies the same binding check to imported events and full-log surface folds', () => { + const { session } = opened() + const invalid: SessionEvent<'developer/message'> = { + type: 'developer/message', seq: SessionSeq(3), time: 4, surfaceOp: 'append', + data: { turn: 1, step: 1, headerSeq: SessionSeq(0), message: addition() }, + } + const events = [...session.snapshotEvents(), invalid] + expect(() => Session.create(SessionId('bad-import'), events)).toThrow('earlier request/header') + expect(() => foldSurface(events)).toThrow('earlier request/header') + }) +}) diff --git a/packages/core/session/tests/fork.spec.ts b/packages/core/session/tests/fork.spec.ts index d67538ded8..1fa38bc2e1 100644 --- a/packages/core/session/tests/fork.spec.ts +++ b/packages/core/session/tests/fork.spec.ts @@ -1,8 +1,9 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import { createUserMessage, ToolCallId , createMessage } from '@deepseek-ai/dsh-llm' -import SessionStore, { Session, SessionForkError, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' -import type { SessionEvent, TurnEndReason } from '@deepseek-ai/dsh-session' +import { createUserMessage, ToolCallId, createMessage } from '@deepseek-ai/dsh-llm' +import type { MessageSource } from '@deepseek-ai/dsh-llm' +import SessionStore, { Session, SessionForkError, SessionId, SessionLogOffset, SessionSeq, TOOL_NOT_STARTED, TOOL_OUTCOME_UNKNOWN } from '@deepseek-ai/dsh-session' +import type { SessionEvent, SurfaceEvent, TurnEndReason } from '@deepseek-ai/dsh-session' declare module '@deepseek-ai/dsh-session/types' { interface SessionEventMap { @@ -85,7 +86,8 @@ describe('SessionStore.fork', () => { expect(child.snapshotEvents()).not.toBe(source.snapshotEvents()) expect(child.snapshotEvents()[1]).not.toBe(source.snapshotEvents()[1]) expect(() => { - firstUserMessage(child.snapshotEvents()).data.content[0] = { type: 'text', text: 'child mutation' } + (firstUserMessage(child.snapshotEvents()).data as unknown as { content: { type: string; text?: string }[] }).content[0] + = { type: 'text', text: 'child mutation' } }).toThrow(TypeError) expect(firstUserMessage(source.snapshotEvents()).data.content).toEqual([{ type: 'text', text: 'hello' }]) expect(firstUserMessage(child.snapshotEvents()).data.content).toEqual([{ type: 'text', text: 'hello' }]) @@ -172,7 +174,7 @@ describe('SessionStore.fork', () => { const boundary = child.snapshotEvents().at(-1) expect(boundary).toMatchObject({ type: 'session/end-seed' }) expect(boundary!.seq).toBeGreaterThan(open.seq) - expect(child.firstLiveSeq).toBe(open.seq + 1) + expect(child.firstLiveSeq).toBe(open.seq + 2) expect(inherited(child).at(-1)).toMatchObject({ type: 'test/bracket-open', data: { id: 'op-1' } }) }) @@ -231,73 +233,6 @@ describe('SessionStore.fork', () => { .toThrow(new SessionForkError('session "same-id" is not the live store instance', 'SESSION_NOT_LIVE')) }) - it('rejects selected slices whose boundary is inside an open turn', async () => { - const { ctx, sessions } = await setup() - const cases: [string, (session: Session) => number][] = [ - ['turn/start', (session) => { - session.append('turn/start', { turn: 1 }) - return lastSeq(session) - }], - ['step/start', (session) => { - session.append('turn/start', { turn: 1 }) - session.append('step/start', { turn: 1, step: 1 }) - return lastSeq(session) - }], - ['user/message', (session) => { - session.append('turn/start', { turn: 1 }) - session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'open' }], source: { kind: 'user' }, - }), { surfaceOp: 'append' }) - return lastSeq(session) - }], - ['assistant/message', (session) => { - session.append('turn/start', { turn: 1 }) - session.append('step/start', { turn: 1, step: 1 }) - session.append('assistant/message', { - stream: [], - turn: 1, step: 1, - message: createMessage({ - role: 'assistant', - content: [{ type: 'text', text: 'partial' }], - source: { - kind: 'model', - ...{ provider: 'mock', model: 'mock' }, - }, - }), - }, { surfaceOp: 'append' }) - return lastSeq(session) - }], - ['tool/call', (session) => { - const callId = ToolCallId('call-open') - session.append('turn/start', { turn: 1 }) - session.append('step/start', { turn: 1, step: 1 }) - session.append('assistant/message', { - stream: [], - turn: 1, - step: 1, - message: createMessage({ - role: 'assistant', - content: [{ type: 'tool-call', id: callId, name: 'bash', arguments: '{}' }], - source: { - kind: 'model', - ...{ provider: 'mock', model: 'mock' }, - }, - }), - }, { surfaceOp: 'append' }) - session.append('tool/call', { turn: 1, step: 1, callId, name: 'bash', arguments: '{}' }) - return lastSeq(session) - }], - ] - - for (const [lastType, build] of cases) { - const source = ctx.sessions.create(SessionId(`open-${lastType}`)) - const boundary = build(source) - - expect(() => sessions.fork(source, SessionSeq(boundary))) - .toThrow(new SessionForkError(`fork boundary ${boundary} in session "open-${lastType}" ends inside open turn 1`, 'OPEN_TURN')) - } - }) - it('rejects a child session id that is already live with a typed fork error', async () => { const { ctx, sessions } = await setup() const source = ctx.sessions.create(SessionId('parent')) @@ -318,3 +253,220 @@ describe('SessionStore.fork', () => { .toThrow(new SessionForkError('session "child" already exists', 'SESSION_ALREADY_EXISTS')) }) }) + +describe('fork boundaries inside an open turn', () => { + /** Open turn 2 after a closed turn 1 and return the source. */ + async function openTurnSource(id: string): Promise<{ ctx: Context; sessions: SessionStore; source: Session }> { + const { ctx, sessions } = await setup() + const source = ctx.sessions.create(SessionId(id)) + appendClosedTurn(source, 1, 'first') + source.append('turn/start', { turn: 2 }) + return { ctx, sessions, source } + } + + /** Append the open step + assistant tool request of turn 2. */ + function appendToolRequest(session: Session, callId: ToolCallId): void { + session.append('step/start', { turn: 2, step: 1 }) + session.append('assistant/message', { + stream: [], + turn: 2, step: 1, + message: createMessage({ + role: 'assistant', + content: [{ type: 'tool-call', id: callId, name: 'bash', arguments: '{}' }], + source: { + kind: 'model', + ...{ provider: 'mock', model: 'mock' }, + }, + }), + }, { surfaceOp: 'append' }) + } + + it('closes an empty open turn with a synthetic turn/end {forked} outside seedLength', async () => { + const { sessions, source } = await openTurnSource('open-empty') + + const child = sessions.fork(source, lastSeq(source), SessionId('open-empty-child')) + + const seed = child.snapshotEvents() + expect(seed.slice(0, source.snapshotEvents().length)).toEqual(source.snapshotEvents()) + expect(seed.at(-1)).toMatchObject({ + type: 'turn/end', + data: { turn: 2, reason: { kind: 'forked' } }, + }) + // The closer is child work: `seedLength` names only events that exist in + // the parent's log, so telemetry receivers stitching a fork's prefix from + // the parent's stream on `(parent_id, seed_length)` read exactly the + // copied prefix. + expect(child.inheritedEventCount).toBe(source.snapshotEvents().length) + }) + + it('closes only the turn when the cut lands on a closed step boundary', async () => { + const { sessions, source } = await openTurnSource('open-step-closed') + source.append('step/start', { turn: 2, step: 1 }) + source.append('assistant/message', { + stream: [], + turn: 2, step: 1, + message: createMessage({ + role: 'assistant', + content: [{ type: 'text', text: 'step done' }], + source: { + kind: 'model', + ...{ provider: 'mock', model: 'mock' }, + }, + }), + }, { surfaceOp: 'append' }) + source.append('step/end', { turn: 2, step: 1 }) + + const child = sessions.fork(source, lastSeq(source), SessionId('open-step-closed-child')) + + expect(child.snapshotEvents().slice(source.snapshotEvents().length + 1).map(e => e.type)).toEqual(['turn/end']) + }) + + it('answers an assistant call cut before its tool/call with a forked not-started error result', async () => { + const { sessions, source } = await openTurnSource('open-not-started') + appendToolRequest(source, ToolCallId('call-ns')) + + const child = sessions.fork(source, lastSeq(source), SessionId('open-not-started-child')) + + const closers = child.snapshotEvents().slice(source.snapshotEvents().length + 1) + expect(closers.map(e => e.type)).toEqual(['tool/result', 'step/end', 'turn/end']) + const result = closers[0]! + expect(result.type === 'tool/result' && result.data).toMatchObject({ + message: { + id: expect.stringMatching(/^forked-tool-result-call-ns-/) as unknown, + source: { callId: ToolCallId('call-ns') }, + }, + error: { name: 'ToolNotStartedError', code: TOOL_NOT_STARTED }, + }) + // The synthetic result is part of the child's model-visible history, not a + // request-time patch: the derived messages end with the error tool result. + const derived = child.deriveMessages() + expect(derived.at(-1)).toMatchObject({ + role: 'tool', + source: { kind: 'tool', callId: ToolCallId('call-ns') }, + toolCallId: ToolCallId('call-ns'), + isError: true, + content: [{ type: 'text' }], + }) + }) + + it('answers a dispatched call cut before its result with an unknown-outcome error citing the tool/call', async () => { + const { sessions, source } = await openTurnSource('open-unknown') + appendToolRequest(source, ToolCallId('call-uo')) + const call = source.append('tool/call', { turn: 2, step: 1, callId: ToolCallId('call-uo'), name: 'bash', arguments: '{}' }) + + const child = sessions.fork(source, lastSeq(source), SessionId('open-unknown-child')) + + const closers = child.snapshotEvents().slice(source.snapshotEvents().length + 1) + expect(closers.map(e => e.type)).toEqual(['tool/result', 'step/end', 'turn/end']) + const result = closers[0]! + expect(result.type === 'tool/result' && result.data.error).toEqual({ + name: 'ToolOutcomeUnknownError', code: TOOL_OUTCOME_UNKNOWN, + }) + expect((result as SurfaceEvent).sourceEventSeqs).toEqual([call.seq]) + }) + + it('omits a failed assistant attempt from derived history', async () => { + const { sessions, source } = await openTurnSource('open-mid-stream') + source.append('step/start', { turn: 2, step: 1 }) + source.append('assistant/attempt', { + turn: 2, step: 1, stream: [], + }) + + const child = sessions.fork(source, lastSeq(source), SessionId('open-mid-stream-child')) + + expect(child.snapshotEvents().slice(source.snapshotEvents().length + 1).map(e => e.type)).toEqual(['step/end', 'turn/end']) + expect(child.deriveMessages().some(message => message.role === 'assistant')).toBe(false) + }) + + it.each([false, true])('preserves a closed step with an unanswered call (turn ended: %s)', async (turnEnded) => { + const { sessions, source } = await openTurnSource('dangling-closed-step') + appendToolRequest(source, ToolCallId('call-dangling')) + source.append('tool/call', { + turn: 2, step: 1, callId: ToolCallId('call-dangling'), name: 'bash', arguments: '{}', + }) + source.append('step/end', { turn: 2, step: 1 }) + if (turnEnded) { + source.append('turn/end', { + turn: 2, reason: { kind: 'error', error: { message: 'scheduler failed', code: 'UNKNOWN' } }, + }) + } + const copiedPrefix = source.snapshotEvents() + + const child = sessions.fork(source) + + expect(inherited(child).slice(0, copiedPrefix.length)).toEqual(copiedPrefix) + expect(child.snapshotEvents().slice(copiedPrefix.length + 1)).toEqual(turnEnded ? [] : [{ + type: 'turn/end', seq: SessionSeq(copiedPrefix.length + 1), time: copiedPrefix.at(-1)!.time, + data: { turn: 2, reason: { kind: 'forked' } }, + }]) + expect(child.inheritedEventCount).toBe(copiedPrefix.length) + expect(child.deriveMessages()).toEqual(source.deriveMessages()) + }) + + it('leaves a plugin bracket left open at the cut untouched (log-only locks belong to their owner)', async () => { + const { sessions, source } = await openTurnSource('open-bracket') + source.append('test/bracket-open', { id: 'op-live' }) + + const child = sessions.fork(source, lastSeq(source), SessionId('open-bracket-child')) + + const closers = child.snapshotEvents().slice(source.snapshotEvents().length + 1) + expect(closers.map(e => e.type)).toEqual(['turn/end']) + // The unmatched bracket sits before the child's end-seed marker, so its + // owning plugin decides its staleness from that boundary. + expect(child.snapshotEvents()[child.inheritedEventCount]).toMatchObject({ type: 'session/end-seed', data: { inherited: true } }) + }) +}) + +describe('fork boundaries around a surface replacement', () => { + /** + * A source whose open turn 2 replaces turn 1's user message with a summary + * (the compaction surface pattern: a `user/message` with a range replace op). + */ + async function replacementSource(id: string): Promise<{ + sessions: SessionStore + source: Session + replacedSeq: SessionSeq + replacementSeq: SessionSeq + }> { + const { ctx, sessions } = await setup() + const source = ctx.sessions.create(SessionId(id)) + appendClosedTurn(source, 1, 'original request') + const replacedSeq = firstUserMessage(source.snapshotEvents()).seq + source.append('turn/start', { turn: 2 }) + const replacement = source.append('user/message', createUserMessage({ + content: [{ type: 'text', text: 'summary of earlier work' }], + source: { + kind: 'compact-checkpoint', + compactionId: 'open-bracket' as Extract['compactionId'], + }, + }), { + surfaceOp: { op: 'replace', startSeq: replacedSeq, endSeq: replacedSeq }, + sourceEventSeqs: [replacedSeq], + }) + return { sessions, source, replacedSeq, replacementSeq: replacement.seq } + } + + it('derives the original message for a cut before the replacement', async () => { + const { sessions, source, replacementSeq } = await replacementSource('replace-before') + + const child = sessions.fork(source, SessionSeq(replacementSeq - 1), SessionId('replace-before-child')) + + expect(child.deriveMessages().map(message => message.content)).toEqual([ + [{ type: 'text', text: 'original request' }], + ]) + }) + + it('derives the compacted surface for a cut after the replacement', async () => { + const { sessions, source, replacementSeq } = await replacementSource('replace-after') + + const child = sessions.fork(source, replacementSeq, SessionId('replace-after-child')) + + expect(child.deriveMessages().map(message => message.content)).toEqual([ + [{ type: 'text', text: 'summary of earlier work' }], + ]) + expect(child.snapshotEvents().at(-1)).toMatchObject({ + type: 'turn/end', + data: { turn: 2, reason: { kind: 'forked' } }, + }) + }) +}) diff --git a/packages/core/session/tests/invariant.spec.ts b/packages/core/session/tests/invariant.spec.ts index 9b8b281cf5..db75fbc744 100644 --- a/packages/core/session/tests/invariant.spec.ts +++ b/packages/core/session/tests/invariant.spec.ts @@ -1,11 +1,18 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createScope, scopeTarget } from '@deepseek-ai/dsh-scope' -import { createSystemMessage, createUserMessage, ToolCallId, createMessage, createToolResultMessage, freezeMessage } from '@deepseek-ai/dsh-llm' +import { createDeveloperMessage, createSystemMessage, createUserMessage, ToolCallId, createMessage, createToolResultMessage, freezeMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, SessionSeq, TOOL_NOT_STARTED } from '@deepseek-ai/dsh-session' import * as SessionInvariant from '@deepseek-ai/dsh-session/invariant' import InvariantRegistry, { InvariantError } from '@deepseek-ai/dsh-invariants' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + async function setup(): Promise<{ ctx: Context; fiber: Awaited> }> { const ctx = new Context() await ctx.plugin(SessionStore) @@ -31,6 +38,27 @@ describe('session-log invariants', () => { }).not.toThrow() }) + it('requires developer messages to belong to the open turn and step', async () => { + const { ctx } = await setup() + try { + const session = ctx.sessions.create() + const message = createDeveloperMessage({ content: [{ type: 'tool-removal', toolName: 'search' }], source: { kind: 'test' } }) + const append = (turn: number, step: number) => session.append('developer/message', { turn, step, message }, { surfaceOp: 'append' }) + expect(() => append(1, 1)).toThrow('developer/message names turn 1/step 1') + session.append('turn/start', { turn: 1 }) + expect(() => append(1, 1)).toThrow('developer/message names turn 1/step 1') + session.append('step/start', { turn: 1, step: 1 }) + expect(() => append(2, 1)).toThrow('developer/message names turn 2/step 1') + expect(() => append(1, 2)).toThrow('developer/message names turn 1/step 2') + expect(() => append(1, 1)).not.toThrow() + expect(session.deriveMessages()).toEqual([message]) + session.append('step/end', { turn: 1, step: 1 }) + expect(() => append(1, 1)).toThrow('developer/message names turn 1/step 1') + } finally { + await ctx.fiber.dispose() + } + }) + it('accepts a well-formed turn, step, and tool sequence', async () => { const { ctx } = await setup() const session = ctx.sessions.create() @@ -156,7 +184,7 @@ describe('session-log invariants', () => { const outside = (await setup()).ctx.sessions.create() expect(() => outside.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'idle context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: 'append' })).not.toThrow() // Route capacity is core execution state like the header beside it. expect(() => outside.append('request/context', { @@ -237,7 +265,7 @@ describe('session-log invariants', () => { it('requires a system/message to name the open step', async () => { const session = (await setup()).ctx.sessions.create() session.append('turn/start', { turn: 1 }) - const message = createSystemMessage('You are terse.', '@deepseek-ai/dsh-system-prompt') + const message = createSystemMessage('You are terse.') expect(() => session.append('system/message', { turn: 1, step: 1, message }, { surfaceOp: 'append' })) .toThrow(/open is turn 1\/step null/) session.append('step/start', { turn: 1, step: 1 }) @@ -288,10 +316,7 @@ describe('session-log invariants', () => { ...original.data, message: freezeMessage({ ...original.data.message, - content: [{ - ...original.data.message.content[0], - content: [{ type: 'text', text: 'pruned' }], - }] satisfies typeof original.data.message.content, + content: [{ type: 'text', text: 'pruned' }], }), }, { surfaceOp: { op: 'replace', startSeq: original.seq, endSeq: original.seq }, @@ -327,10 +352,7 @@ describe('session-log invariants', () => { ...original.data, message: freezeMessage({ ...original.data.message, - content: [{ - ...original.data.message.content[0], - content: [{ type: 'text', text: 'pruned' }], - }] satisfies typeof original.data.message.content, + content: [{ type: 'text', text: 'pruned' }], }), }, { surfaceOp: { op: 'replace', startSeq: original.seq, endSeq: original.seq }, diff --git a/packages/core/session/tests/properties.spec.ts b/packages/core/session/tests/properties.spec.ts index 07bf37ac02..cbdcbc8148 100644 --- a/packages/core/session/tests/properties.spec.ts +++ b/packages/core/session/tests/properties.spec.ts @@ -164,11 +164,11 @@ describe('Session properties', () => { const messages = session.deriveMessages() const before = structuredClone(session.snapshotEvents()) for (const m of messages) { - expect(['user', 'assistant', 'system']).toContain(m.role) + expect(['user', 'assistant', 'system', 'tool']).toContain(m.role) // Derived messages are frozen shared projections: mutation THROWS // (strict mode) instead of relying on per-call clones for isolation. expect(Object.isFrozen(m)).toBe(true) - expect(() => { m.content.push({ type: 'text', text: 'mutation' }) }).toThrow(TypeError) + expect(() => { (m.content as unknown as { type: string; text?: string }[]).push({ type: 'text', text: 'mutation' }) }).toThrow(TypeError) } expect(session.snapshotEvents()).toEqual(before) })) diff --git a/packages/core/session/tests/repair.spec.ts b/packages/core/session/tests/repair.spec.ts index d4955d0110..6be64dffe6 100644 --- a/packages/core/session/tests/repair.spec.ts +++ b/packages/core/session/tests/repair.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { ToolCallId , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm' import { interruptedTurnClosers as repairInterruptedTurn, SessionSeq, TOOL_NOT_STARTED, TOOL_OUTCOME_UNKNOWN } from '../src/index.ts' +import { openTurnClosers as closeOpenTurn, type OpenTurnCloseCause } from '../src/repair.ts' import type { SessionEvent as LogicalSessionEvent, SurfaceEvent } from '../src/index.ts' interface SessionEvent { @@ -16,6 +17,11 @@ function interruptedTurnClosers(events: readonly SessionEvent[]): LogicalSession return repairInterruptedTurn(events as unknown as readonly LogicalSessionEvent[]) } +function openTurnClosers(events: readonly SessionEvent[], cause: OpenTurnCloseCause): LogicalSessionEvent[] { + for (const event of events) SessionSeq(event.seq) + return closeOpenTurn(events as unknown as readonly LogicalSessionEvent[], cause) +} + /** * Unit coverage for the crash-recovery closer synthesis. The persistence * contract exercises it end-to-end through the real JSONL provider; these tests pin the @@ -28,26 +34,28 @@ function interruptedTurnClosers(events: readonly SessionEvent[]): LogicalSession const userTurnStart = (turn: number, seq: number): SessionEvent => ({ type: 'turn/start', seq, time: seq, data: { turn } }) -describe('interruptedTurnClosers', () => { +const causes: OpenTurnCloseCause[] = [{ kind: 'interrupted' }, { kind: 'forked' }] + +describe.each(causes)('openTurnClosers (cause %o)', (cause) => { it('returns nothing for a balanced log (ends on turn/end)', () => { const balanced: SessionEvent[] = [ userTurnStart(1, 0), { type: 'turn/end', seq: 1, time: 1, data: { turn: 1, reason: { kind: 'completed' } } }, ] - expect(interruptedTurnClosers(balanced)).toEqual([]) + expect(openTurnClosers(balanced, cause)).toEqual([]) }) it('returns nothing for an empty log', () => { - expect(interruptedTurnClosers([])).toEqual([]) + expect(openTurnClosers([], cause)).toEqual([]) }) - it('closes an open turn with no open step (turn/end {interrupted} only)', () => { + it('closes an open turn with no open step (turn/end with the cause reason only)', () => { const events: SessionEvent[] = [userTurnStart(1, 0)] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) expect(closers.map(e => e.type)).toEqual(['turn/end']) const end = closers[0]! expect(end.seq).toBe(1) - expect(end.type === 'turn/end' && end.data.reason).toEqual({ kind: 'interrupted' }) + expect(end.type === 'turn/end' && end.data.reason).toEqual({ kind: cause.kind }) }) it('closes an open step before the turn (step/end then turn/end)', () => { @@ -55,7 +63,7 @@ describe('interruptedTurnClosers', () => { userTurnStart(1, 0), { type: 'step/start', seq: 1, time: 1, data: { turn: 1, step: 1 } }, ] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) expect(closers.map(e => e.type)).toEqual(['step/end', 'turn/end']) expect(closers.map(e => e.seq)).toEqual([2, 3]) }) @@ -79,7 +87,7 @@ describe('interruptedTurnClosers', () => { }), } }, ] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) // tool/result (for the orphaned call) → step/end → turn/end, contiguous seqs. expect(closers.map(e => e.type)).toEqual(['tool/result', 'step/end', 'turn/end']) expect(closers.map(e => e.seq)).toEqual([3, 4, 5]) @@ -88,13 +96,18 @@ describe('interruptedTurnClosers', () => { turn: 2, step: 1, message: { + id: `${cause.kind}-tool-result-call-1-3`, source: { callId: ToolCallId('call-1') }, - content: [{ isError: true }], + role: 'tool', + toolCallId: ToolCallId('call-1'), + isError: true, }, error: { code: TOOL_NOT_STARTED }, }) - expect(result.type === 'tool/result' && result.data.message.content[0].content).toEqual([{ - type: 'text', text: 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.', + expect(result.type === 'tool/result' && result.data.message.content).toEqual([{ + type: 'text', text: cause.kind === 'forked' + ? 'The history inherited by this branch has no record of this tool call starting. The parent session may have executed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.' + : 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.', }]) }) @@ -125,11 +138,11 @@ describe('interruptedTurnClosers', () => { } }, ] // The call is answered, so only the open step + turn need closing. - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) expect(closers.map(e => e.type)).toEqual(['step/end', 'turn/end']) }) - it('does NOT synthesize a result after the owning step already closed', () => { + it('preserves an unanswered assistant call after the owning step already closed', () => { const events: SessionEvent[] = [ userTurnStart(2, 0), { type: 'step/start', seq: 1, time: 1, data: { turn: 2, step: 1 } }, @@ -149,14 +162,15 @@ describe('interruptedTurnClosers', () => { { type: 'step/end', seq: 3, time: 3, data: { turn: 2, step: 1 } }, ] - const closers = interruptedTurnClosers(events) - expect(closers.map(e => e.type)).toEqual(['turn/end']) - expect(closers[0]?.seq).toBe(4) + const closers = openTurnClosers(events, cause) + expect(closers).toEqual([{ + type: 'turn/end', seq: 4, time: 3, data: { turn: 2, reason: cause }, + }]) }) it('synthesizes results only for the still-open turn, not a committed earlier turn', () => { - // Turn 1 completed with its own tool call+result (balanced). Turn 2 crashed - // with an unanswered call. Only turn 2's call must get a synthetic result. + // Turn 1 completed with its own tool call+result (balanced). Turn 2 was cut + // open with an unanswered call. Only turn 2's call must get a synthetic result. const events: SessionEvent[] = [ userTurnStart(1, 0), { type: 'step/start', seq: 1, time: 1, data: { turn: 1, step: 1 } }, @@ -199,7 +213,7 @@ describe('interruptedTurnClosers', () => { }), } }, ] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) expect(closers.map(e => e.type)).toEqual(['tool/result', 'step/end', 'turn/end']) const result = closers[0]! expect(result.type === 'tool/result' && result.data.message.source.callId).toBe('new-call') @@ -223,7 +237,7 @@ describe('interruptedTurnClosers', () => { }, }), } }, - // call-a got answered before the crash; call-b did not. + // call-a got answered before the cut; call-b did not. { type: 'tool/result', seq: 3, time: 3, data: { turn: 1, step: 1, message: createToolResultMessage({ @@ -233,7 +247,7 @@ describe('interruptedTurnClosers', () => { }), } }, ] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) expect(closers.map(e => e.type)).toEqual(['tool/result', 'step/end', 'turn/end']) const result = closers[0]! expect(result.type === 'tool/result' && result.data.message.source.callId).toBe('call-b') @@ -258,7 +272,7 @@ describe('interruptedTurnClosers', () => { } }, { type: 'tool/call', seq: 3, time: 3, data: { turn: 1, step: 1, callId: ToolCallId('call-1'), name: 'bash', arguments: '{}' } }, ] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) expect(closers.map(e => e.type)).toEqual(['tool/result', 'step/end', 'turn/end']) const result = closers[0]! expect((result as SurfaceEvent).surfaceOp).toBe('append') @@ -266,11 +280,11 @@ describe('interruptedTurnClosers', () => { expect(result.type === 'tool/result' && result.data.error).toEqual({ name: 'ToolOutcomeUnknownError', code: TOOL_OUTCOME_UNKNOWN, }) - if (result.type !== 'tool/result' || result.data.message.content[0].content[0]?.type !== 'text') { + if (result.type !== 'tool/result' || result.data.message.content[0]?.type !== 'text') { throw new Error('expected a text tool result') } - expect(result.data.message.content[0].content[0].text).toContain('retry only if the operation is read-only or idempotent') - expect(result.data.message.content[0].content[0].text).toContain('first verify external state or ask the user') + expect(result.data.message.content[0].text).toContain('retry only if the operation is read-only or idempotent') + expect(result.data.message.content[0].text).toContain('first verify external state or ask the user') }) it('handles tool/call without a matching assistant/message entry gracefully', () => { @@ -281,8 +295,89 @@ describe('interruptedTurnClosers', () => { { type: 'step/start', seq: 1, time: 1, data: { turn: 1, step: 1 } }, { type: 'tool/call', seq: 2, time: 2, data: { turn: 1, step: 1, callId: ToolCallId('orphan'), name: 'bash', arguments: '{}' } }, ] - const closers = interruptedTurnClosers(events) + const closers = openTurnClosers(events, cause) // No pending calls → no synthetic tool/result, just step/end + turn/end. expect(closers.map(e => e.type)).toEqual(['step/end', 'turn/end']) }) }) + +describe('openTurnClosers model-visible wording', () => { + /** An open turn with one unanswered call; `started` also logs its tool/call. */ + function openCall(started: boolean): SessionEvent[] { + const events: SessionEvent[] = [ + userTurnStart(1, 0), + { type: 'step/start', seq: 1, time: 1, data: { turn: 1, step: 1 } }, + { type: 'assistant/message', seq: 2, time: 2, data: { + turn: 1, step: 1, + message: createMessage({ + role: 'assistant', + content: [ + { type: 'tool-call', id: ToolCallId('call-1'), name: 'bash', arguments: '{}' }, + ], + source: { + kind: 'model', + ...{ provider: 'mock', model: 'mock' }, + }, + }), + } }, + ] + if (started) { + events.push({ type: 'tool/call', seq: 3, time: 3, data: { turn: 1, step: 1, callId: ToolCallId('call-1'), name: 'bash', arguments: '{}' } }) + } + return events + } + + function resultText(closers: LogicalSessionEvent[]): string { + const result = closers[0] + if (result?.type !== 'tool/result' || result.data.message.content[0]?.type !== 'text') { + throw new Error('expected a text tool result') + } + return result.data.message.content[0].text + } + + // The exact wording is model-visible: pinned verbatim per cause and lifecycle. + it.each([ + [ + { kind: 'interrupted' } satisfies OpenTurnCloseCause, + false, + 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.', + ], + [ + { kind: 'interrupted' } satisfies OpenTurnCloseCause, + true, + 'The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.', + ], + [ + { kind: 'forked' } satisfies OpenTurnCloseCause, + false, + 'The history inherited by this branch has no record of this tool call starting. The parent session may have executed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.', + ], + [ + { kind: 'forked' } satisfies OpenTurnCloseCause, + true, + 'The history inherited by this branch records this tool call starting but does not include its result. The parent session may have completed it after the fork point. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly.', + ], + ])('cause %o, started=%s pins its exact text', (cause, started, text) => { + expect(resultText(openTurnClosers(openCall(started), cause))).toBe(text) + }) + + it('shares the error codes across causes: they state the same call lifecycle fact', () => { + for (const cause of causes) { + const notStarted = openTurnClosers(openCall(false), cause)[0] + expect(notStarted?.type === 'tool/result' && notStarted.data.error).toEqual({ + name: 'ToolNotStartedError', code: TOOL_NOT_STARTED, + }) + const started = openTurnClosers(openCall(true), cause)[0] + expect(started?.type === 'tool/result' && started.data.error).toEqual({ + name: 'ToolOutcomeUnknownError', code: TOOL_OUTCOME_UNKNOWN, + }) + } + }) + + it('interruptedTurnClosers is the public interrupted-cause entry (cause selection stays internal)', () => { + const events = openCall(true) + expect(interruptedTurnClosers(events)).toEqual(openTurnClosers(events, { kind: 'interrupted' })) + const end = interruptedTurnClosers(events).at(-1) + expect(end?.type === 'turn/end' && end.data.reason).toEqual({ kind: 'interrupted' }) + }) +}) diff --git a/packages/core/session/tests/sequence-types.spec.ts b/packages/core/session/tests/sequence-types.spec.ts index d20d2c721f..29757a8ab2 100644 --- a/packages/core/session/tests/sequence-types.spec.ts +++ b/packages/core/session/tests/sequence-types.spec.ts @@ -107,6 +107,23 @@ describe('Session log positions', () => { expect(child.isOwnSeq(SessionSeq(3))).toBe(true) }) + it('accepts child closers after the inherited marker and rejects a later inherited marker', () => { + const id = SessionId('marked-fork') + const header: SessionHeader = { version: SESSION_FORMAT_VERSION, id, createdAt: 1, isSeeded: true } + const seed = [ + { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1 } }, + { type: 'session/end-seed', seq: SessionSeq(1), time: 2, data: { inherited: true } }, + { type: 'turn/end', seq: SessionSeq(2), time: 3, data: { turn: 1, reason: { kind: 'forked' } } }, + ] as const + const child = Session.create(id, seed, header, SessionLogOffset(1)) + expect(child.snapshotEvents()).toEqual(seed) + expect(child.ownEvents().map(event => event.type)).toEqual(['session/end-seed', 'turn/end']) + expect(child.firstLiveSeq).toBe(3) + expect(() => Session.create(id, [...seed, { + type: 'session/end-seed', seq: SessionSeq(3), time: 4, data: { inherited: true }, + }], header, SessionLogOffset(1))).toThrow('final inherited marker') + }) + it('requires a separately supplied inherited cut for a seeded header', () => { const id = SessionId('missing-cut') expect(() => Session.create(id, [], { diff --git a/packages/core/session/tests/session.spec.ts b/packages/core/session/tests/session.spec.ts index d6762ba147..2a253fc128 100644 --- a/packages/core/session/tests/session.spec.ts +++ b/packages/core/session/tests/session.spec.ts @@ -1,6 +1,8 @@ import { describe, expect, expectTypeOf, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import { createSystemMessage, createUserMessage, ToolCallId, createMessage, createToolResultMessage, MessageId, ReasoningEffortId } from '@deepseek-ai/dsh-llm' +import { createDeveloperMessage, createSystemMessage, createUserMessage, ToolCallId, createMessage, createToolResultMessage, MessageId, ReasoningEffortId } from '@deepseek-ai/dsh-llm' +import type { ContentBlock } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { adoptSessionEvent, SESSION_FORMAT_VERSION, @@ -13,6 +15,13 @@ import SessionStore, { } from '@deepseek-ai/dsh-session' import type { CreateSessionOptions, SessionEventType, SessionHeader, SessionSurface } from '@deepseek-ai/dsh-session' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + 'watcher': { kind: 'watcher' } & ContextFormed + } +} + describe('Session', () => { it('exposes one stable readonly surface view', () => { const session = Session.create(SessionId('surface-view')) @@ -58,10 +67,10 @@ describe('Session', () => { session.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) const messages = session.deriveMessages() - expect(messages.map(m => m.role)).toEqual(['user', 'assistant', 'user']) + expect(messages.map(m => m.role)).toEqual(['user', 'assistant', 'tool']) // raw chunks must NOT appear in derived history expect(messages[1]!.content).toHaveLength(2) - expect(messages[2]!.content[0]).toMatchObject({ type: 'tool-result', toolCallId: ToolCallId('c1') }) + expect(messages[2]).toMatchObject({ role: 'tool', content: [{ type: 'text', text: 'ok' }] }) }) it('accepts and round-trips a max-tokens turn/end reason', () => { @@ -92,7 +101,7 @@ describe('Session', () => { const session = Session.create(SessionId('s2')) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'file changed: a.ts' }], - source: { kind: 'plugin', plugin: 'watcher' }, + source: { kind: 'watcher' }, }), { surfaceOp: 'append' }) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'focus on tests' }], @@ -110,13 +119,14 @@ describe('Session', () => { const session = Session.create(SessionId('s2-raw')) const message = createUserMessage({ content: [{ type: 'text', text: 'Additional instructions from: pkg/AGENTS.md' }], - source: { kind: 'plugin', plugin: 'agent-instructions' }, + source: { kind: 'agent-instructions', form: 'instructions', changes: [] }, }) session.append('user/message', message, { surfaceOp: 'append' }) expect(session.deriveMessages()).toEqual([message]) const event = session.snapshotEvents()[0] - expect(event?.type === 'user/message' && event.data.source).toEqual({ kind: 'plugin', plugin: 'agent-instructions' }) + expect(event?.type === 'user/message' && event.data.source) + .toEqual({ kind: 'agent-instructions', form: 'instructions', changes: [] }) }) it('replays identically from a seeded event log', () => { @@ -290,12 +300,9 @@ describe('Session', () => { } const tool = { id: 'tool', - role: 'user', - content: [{ - type: 'tool-result', - toolCallId: 'call', - content: [{ type: 'text', text: 'result' }], - }], + role: 'tool', + toolCallId: 'call', + content: [{ type: 'text', text: 'result' }], source: { kind: 'tool', callId: 'call' }, } const invalid = [ @@ -362,7 +369,7 @@ describe('Session', () => { data: { turn: 1, step: 1, - message: { ...user, id: 'system', source: { kind: 'plugin', plugin: 'prompt' } }, + message: { ...user, id: 'system', source: { kind: 'system-prompt' } }, }, }, message: 'message must have role "system"', @@ -374,22 +381,22 @@ describe('Session', () => { data: { turn: 1, step: 1, - message: { ...user, id: 'system', role: 'system', source: { kind: 'plugin', plugin: '' } }, + message: { ...user, id: 'system', role: 'system', source: { kind: 'runtime-context' } }, }, }, - message: 'message must have plugin source', + message: 'message must have system-prompt source', }, { - name: 'tool tuple', + name: 'tool role', event: { type: 'tool/result', seq: 0, time: 1, surfaceOp: 'append', data: { turn: 1, step: 1, - message: { ...tool, content: [{ type: 'text', text: 'not a result' }] }, + message: { ...tool, role: 'user' }, }, }, - message: 'message must contain one tool-result block', + message: 'message must have role "tool"', }, { name: 'tool correlation', @@ -458,7 +465,7 @@ describe('Session', () => { content: [{ type: 'text', text: 'owned' }], source: { kind: 'user' }, }, - } as SessionEvent<'user/message'> + } as unknown as SessionEvent<'user/message'> expect(adoptSessionEvent(owned)).toBe(owned) expect(Object.isFrozen(owned.data)).toBe(true) expect(Object.isFrozen(owned.data.content)).toBe(true) @@ -470,6 +477,19 @@ describe('Session', () => { expect(snapshot.data.content).not.toBe(source.data.content) }) + it('adopts developer messages in place and freezes their nested tool changes', () => { + const event: SessionEvent<'developer/message'> = { + type: 'developer/message', seq: SessionSeq(1), time: 1, surfaceOp: 'append', + data: { turn: 1, step: 1, headerSeq: SessionSeq(0), message: structuredClone(createDeveloperMessage({ + content: [{ type: 'tool-addition', toolName: 'search' }], source: { kind: 'test' }, + })) }, + } + expect(Object.isFrozen(event.data.message)).toBe(false) + expect(adoptSessionEvent(event)).toBe(event) + expect(Object.isFrozen(event.data.message)).toBe(true) + expect(Object.isFrozen(event.data.message.content[0])).toBe(true) + }) + it('adopts a system/message by freezing its message', () => { const event = { type: 'system/message', @@ -479,7 +499,7 @@ describe('Session', () => { data: { turn: 1, step: 1, - message: createSystemMessage('You are terse.', '@deepseek-ai/dsh-system-prompt'), + message: createSystemMessage('You are terse.'), }, } as unknown as SessionEvent const adopted = adoptSessionEvent(event) @@ -585,11 +605,11 @@ describe('Session', () => { const messages = session.deriveMessages() const userBlock = messages[0]!.content[0]! expect(() => { if (userBlock.type === 'text') userBlock.text = 'HACKED' }).toThrow(TypeError) - const toolBlock = messages[1]!.content[0]! + const toolMessage = messages[1]! expect(() => { - if (toolBlock.type === 'tool-result') toolBlock.content.push({ type: 'text', text: 'injected' }) + if (toolMessage.role === 'tool') (toolMessage.content as ContentBlock[]).push({ type: 'text', text: 'injected' }) }).toThrow(TypeError) - expect(() => { messages[0]!.content.push({ type: 'text', text: 'extra' }) }).toThrow(TypeError) + expect(() => { (messages[0]!.content as ContentBlock[]).push({ type: 'text', text: 'extra' }) }).toThrow(TypeError) // The returned ARRAY is the caller's own snapshot, though — reordering it // is the caller's business and never reaches the cache or the log. messages.reverse() @@ -1623,7 +1643,7 @@ describe('SessionStore', () => { expect(() => session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'replacement' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: SessionSeq(2), endSeq: SessionSeq(2) }, sourceEventSeqs: [SessionSeq(2)], diff --git a/packages/core/session/tests/surface.spec.ts b/packages/core/session/tests/surface.spec.ts index c861e17b3b..95d536ec2b 100644 --- a/packages/core/session/tests/surface.spec.ts +++ b/packages/core/session/tests/surface.spec.ts @@ -6,6 +6,7 @@ import { SessionLogOffset, SessionSeq, foldSurface, + snapshotSessionEvent, isAppendSurfaceEvent, isReplacementSurfaceEvent, isSurfaceEligibleType, @@ -13,16 +14,31 @@ import { } from '@deepseek-ai/dsh-session' import { SurfaceManager } from '@deepseek-ai/dsh-session/surface' import { + MessageId, + ToolCallId, createMessage, + createDeveloperMessage, createSystemMessage, createToolResultMessage, createUserMessage, freezeMessage, - ToolCallId, - MessageId, } from '@deepseek-ai/dsh-llm' +import type { ContextFormed, MessageSource } from '@deepseek-ai/dsh-llm' + +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + 'watcher': { kind: 'watcher' } & ContextFormed + } +} type TestSurfaceOp = 'append' | { op: 'replace'; startSeq: number; endSeq: number } +type CheckpointSource = Extract + +/** Build a typed checkpoint source for a surface replacement fixture. */ +function checkpointSource(compactionId: string): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: compactionId as CheckpointSource['compactionId'] } +} function surfaceOp(value: TestSurfaceOp): SurfaceEvent['surfaceOp'] { return value === 'append' @@ -33,7 +49,7 @@ function surfaceOp(value: TestSurfaceOp): SurfaceEvent['surfaceOp'] { function replacementMessage(text: string) { return createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) } @@ -204,7 +220,6 @@ describe('foldSurface tool-result rewrites', () => { ] as const)('rejects a replacement that changes the result block %s', (_field, patch) => { const original = toolResultEvent(SessionSeq(0), 'original') const data = original.data as Extract['data'] - const result = data.message.content[0] const replacement = { ...original, seq: SessionSeq(1), @@ -213,7 +228,7 @@ describe('foldSurface tool-result rewrites', () => { ...data, message: freezeMessage({ ...data.message, - content: [{ ...result, ...patch }] as [typeof result], + ...patch, }), }, surfaceOp: surfaceOp({ op: 'replace', startSeq: 0, endSeq: 0 }), @@ -690,7 +705,7 @@ describe('deriveMessages with surface', () => { it('injected-context and user messages appear on surface', () => { const s = Session.create(SessionId('ctx')) s.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'file changed' }], source: { kind: 'plugin', plugin: 'watcher' }, + content: [{ type: 'text', text: 'file changed' }], source: { kind: 'watcher' }, }), { surfaceOp: 'append' }) s.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'focus' }], @@ -712,7 +727,7 @@ describe('Session.append surface opts', () => { 'user/message', createUserMessage({ content: [{ type: 'text', text: 'h' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: 'append', sourceEventSeqs: sourceSeqs(0, 1) }, ) @@ -833,7 +848,7 @@ describe('surface type guards', () => { it('splits surface events into append-origin and replacement by their marker', () => { const s = surfaceSession() s.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'checkpoint' }], source: { kind: 'plugin', plugin: 'compact' }, + content: [{ type: 'text', text: 'checkpoint' }], source: checkpointSource('surface-compaction-1'), }), { surfaceOp: surfaceOp({ op: 'replace', startSeq: 1, endSeq: 2 }), sourceEventSeqs: sourceSeqs(1, 2) }) const appended = s.snapshotEvents().find(e => e.type === 'user/message')! const replacement = s.snapshotEvents().at(-1)! @@ -881,7 +896,7 @@ describe('SurfaceManager.replaceGeneration', () => { const nodes = s.surface.nodes s.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'summary' }], source: { kind: 'plugin', plugin: 'compact' }, + content: [{ type: 'text', text: 'summary' }], source: checkpointSource('surface-compaction-2'), }), { surfaceOp: { op: 'replace', startSeq: nodes[0]!, endSeq: nodes[1]! }, sourceEventSeqs: [nodes[0]!, nodes[1]!] }) expect(s.surface.replaceGeneration).toBe(1) }) @@ -893,7 +908,7 @@ describe('system/message surface node', () => { type: 'system/message', seq: SessionSeq(seq), time: seq, - data: { turn: 1, step: 1, message: createSystemMessage(text, 'test-plugin') }, + data: { turn: 1, step: 1, message: createSystemMessage(text) }, surfaceOp: surfaceOp(op), ...sources === undefined ? {} : { sourceEventSeqs: sourceSeqs(...sources) }, } @@ -913,13 +928,13 @@ describe('system/message surface node', () => { const s = Session.create(SessionId('sys')) s.append('turn/start', { turn: 1 }) s.append('step/start', { turn: 1, step: 1 }) - s.append('system/message', { turn: 1, step: 1, message: createSystemMessage('be brief', 'p') }, { surfaceOp: 'append' }) + s.append('system/message', { turn: 1, step: 1, message: createSystemMessage('be brief') }, { surfaceOp: 'append' }) s.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'hi' }], source: { kind: 'user' } }), { surfaceOp: 'append' }) expect(s.deriveMessages().map(message => message.role)).toEqual(['system', 'user']) expect(s.deriveMessages()[0]?.content).toEqual([{ type: 'text', text: 'be brief' }]) const head = s.surface.nodes[0] as SessionSeq - s.append('system/message', { turn: 1, step: 1, message: createSystemMessage('', 'p') }, { + s.append('system/message', { turn: 1, step: 1, message: createSystemMessage('') }, { surfaceOp: { op: 'replace', startSeq: head, endSeq: head }, sourceEventSeqs: [head], }) @@ -955,11 +970,55 @@ describe('system/message surface node', () => { expect(plainHead.nodes).toEqual(sourceSeqs(2)) }) - it('rejects a seeded system/message with a non-system role or non-plugin source', () => { + it('rejects a seeded system/message with a non-system role or non-system-prompt source', () => { const good = systemEvent(0, 'v1') const badRole = { ...good, data: { ...good.data, message: { ...(good.data as { message: object }).message, role: 'user' } } } expect(() => Session.create(SessionId('bad-role'), [badRole as SessionEvent])).toThrow(/role "system"/) const badSource = { ...good, data: { ...good.data, message: { ...(good.data as { message: object }).message, source: { kind: 'user' } } } } - expect(() => Session.create(SessionId('bad-source'), [badSource as SessionEvent])).toThrow(/plugin source/) + expect(() => Session.create(SessionId('bad-source'), [badSource as SessionEvent])).toThrow(/system-prompt source/) + }) +}) + + +describe('developer message history', () => { + it.each(['user/message', 'developer/message'] as const)('rejects a mismatched developer role in %s at event admission', (type) => { + const message = createDeveloperMessage({ source: { kind: 'test' }, content: [] }) + const event = { + type, seq: SessionSeq(0), time: 0, surfaceOp: 'append', + data: type === 'user/message' ? message : { turn: 1, step: 1, message: { ...message, role: 'user' } }, + } as unknown as SessionEvent + expect(() => snapshotSessionEvent(event)).toThrow('must occur together') + }) + + it('retains an empty developer node while projecting no message', () => { + const session = Session.create(SessionId('empty-developer')) + const message = createDeveloperMessage({ source: { kind: 'test' }, content: [] }) + const event = session.append('developer/message', { turn: 1, step: 1, message }, { surfaceOp: 'append' }) + expect(session.snapshotEvents()).toContain(event) + expect(session.deriveMessages()).toEqual([]) + const restored = Session.fromRestore(session.id, session.snapshotEvents(), session.header, SessionLogOffset(0), 'shared-frozen') + expect(restored.deriveMessages()).toEqual([]) + }) + + it.each(['tool-addition', 'tool-removal'] as const)('rejects %s in user messages at Session admission', (type) => { + const session = Session.create(SessionId('invalid-tool-change')) + const message = createUserMessage({ source: { kind: 'test' }, content: [{ type, toolName: 'search' }] }) + expect(() => session.append('user/message', message, { surfaceOp: 'append' })).toThrow('developer role') + }) + + it('retains developer blocks through append, replacement, and restoration', () => { + const session = Session.create(SessionId('developer')) + const message = createDeveloperMessage({ source: { kind: 'test' }, content: [{ type: 'tool-addition', toolName: 'search' }] }) + const headerSeq = session.append('request/header', { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [{ name: 'search', description: 'Search', parameters: {} }] } }).seq + const first = session.append('developer/message', { turn: 1, step: 1, headerSeq, message }, { surfaceOp: 'append' }) + expect(session.deriveMessages()).toEqual([message]) + const replacement = createDeveloperMessage({ source: { kind: 'test' }, content: [{ type: 'tool-removal', toolName: 'search' }] }) + session.append('developer/message', { turn: 1, step: 1, message: replacement }, { + surfaceOp: { op: 'replace', startSeq: first.seq, endSeq: first.seq }, sourceEventSeqs: [first.seq], + }) + expect(session.deriveMessages()).toEqual([replacement]) + expect(isSurfaceEligibleType('developer/message')).toBe(true) + const restored = Session.fromRestore(session.id, session.snapshotEvents(), session.header, SessionLogOffset(0), 'shared-frozen') + expect(restored.deriveMessages()).toEqual([replacement]) }) }) diff --git a/packages/core/system-prompt/src/index.ts b/packages/core/system-prompt/src/index.ts index 0003ae7a8d..0a5d7555f0 100644 --- a/packages/core/system-prompt/src/index.ts +++ b/packages/core/system-prompt/src/index.ts @@ -584,10 +584,11 @@ export class SystemPrompt extends Service { const knownNames = new Set() for (const provider of providers) { const result = provider(context) - const schemas = result.schemas.map(({ name, description, parameters }): ToolSchema => ({ + const schemas = result.schemas.map(({ name, description, parameters, deferLoading }): ToolSchema => ({ name, description, parameters: structuredClone(parameters), + ...deferLoading === true ? { deferLoading } : {}, })) const acceptedKnownNames = result.knownNames ?? schemas.map(tool => tool.name) collected.push(...schemas) diff --git a/packages/core/tools/README.i18n.yaml b/packages/core/tools/README.i18n.yaml index 0ea882bf6b..81cbe5aaa8 100644 --- a/packages/core/tools/README.i18n.yaml +++ b/packages/core/tools/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/core/tools/README.md -README.md: 526f04dad93641452033325a73b256d0ae132f00 -README.zh.md: 5a3b6a896db1d32f61f191fdad61a03bd159620e +README.md: b5400d6b8743d904f5ff07a5fef50e041633ffbb +README.zh.md: 1bfd05db5c333215544b515a52364edbd6c126d8 diff --git a/packages/core/tools/README.md b/packages/core/tools/README.md index 526f04dad9..b5400d6b87 100644 --- a/packages/core/tools/README.md +++ b/packages/core/tools/README.md @@ -126,6 +126,8 @@ Under `ptc` or `both`, the registry exposes the reserved `run_code` transport pl New sub-calls use `:ptc:` ids. Consumers treat these ids as opaque and correlate events by exact equality; restored historical ids retain their original bytes. The [PTC mode decision](../../../.agents/notes/implemented/feature/2026-06-15-ptc.md) owns durable naming and restoration rules. +Successful image-bearing subcall results become deferred user-message context with `source.kind` set to `ptc-mode`. Other additional contexts retain their producing tool's attribution. + `run_code` accepts `timeoutMs` when the mounted runtime supports an override; its schema reports the configured default and maximum, the runtime's usage instructions and the Session working directory. The Node default is 120,000 ms with a 600,000 ms cap, including nested tool and approval waits. A wider `sandbox_permissions` mode requires a non-empty `justification` and approval before the program starts. The grant applies to that complete execution; standing Session policy and nested tools retain their own authority. Programs are never replayed automatically: inspect earlier effects before explicitly retrying a denied program. @@ -230,6 +232,8 @@ These limits define when the registry needs special care. They are current packa - **PTC mode intermediate values are execution-local and unbounded by bytes** — they cannot be reconstructed from session replay and may exhaust process or worker memory; only the outer `run_code` output has the worker's configurable hard cap. - **`run_code` state is fresh per run** — a persistent REPL-style kernel is rejected for the MVP, because cross-call state would be invisible to the log. +`defineTool()`, registry schema projection, and system-prompt assembly preserve `deferLoading: true`. The marker requests deferred definition loading and does not imply a `tool-addition` record; the [LLM package](../../../packages/llm/llm/README.md#known-limitations-and-deferred-work) documents provider enforcement limits. + ### Dev Note diff --git a/packages/core/tools/README.zh.md b/packages/core/tools/README.zh.md index 5a3b6a896d..1bfd05db5c 100644 --- a/packages/core/tools/README.zh.md +++ b/packages/core/tools/README.zh.md @@ -126,6 +126,8 @@ ctx.tools.register(defineTool({ 新子调用使用 `:ptc:` 标识。消费方将这些标识视为不透明值,并通过精确相等关联事件;恢复的历史标识保留原始字节。[PTC mode 决策](../../../.agents/notes/implemented/feature/2026-06-15-ptc.zh.md) 负责持久化命名与恢复规则。 +成功且包含图片的子调用结果会成为延后的 user-message 上下文,其 `source.kind` 为 `ptc-mode`。其他 additional context 保留其生产工具的归属。 + 当已挂载运行时支持覆盖时,`run_code` 接受 `timeoutMs`;其 schema 报告配置的默认值和上限、运行时使用说明及 Session 工作目录。Node 默认值为 120,000 ms,上限为 600,000 ms,包含嵌套工具和审批等待。更宽的 `sandbox_permissions` 模式要求非空 `justification`,并在程序启动前获得审批。授权仅用于该次完整执行;常驻 Session 策略与嵌套工具保留各自权限。程序不会自动重放:显式重试被拒程序前,应检查先前已发生的效果。 @@ -230,6 +232,8 @@ Program-only SDK bindings: - **PTC mode 中间值只存在于执行局部,且没有字节上限**:它们无法从会话回放重建,并可能耗尽进程或 worker 内存;只有外层 `run_code` 输出受 worker 可配置的硬上限约束。 - **每次运行都会获得全新的 `run_code` 状态**:MVP 不采用持久 REPL 风格内核,因为跨调用状态不会出现在日志中。 +`defineTool()`、注册表模式投影和系统提示组装会保留 `deferLoading: true`。该标记请求延迟加载工具定义,并不意味着存在 `tool-addition` 记录;提供方执行语义的限制见 [LLM 包](../../../packages/llm/llm/README.zh.md#known-limitations-and-deferred-work)。 + ### 开发备注 diff --git a/packages/core/tools/src/index.ts b/packages/core/tools/src/index.ts index 6be7be61e2..87275e87d0 100644 --- a/packages/core/tools/src/index.ts +++ b/packages/core/tools/src/index.ts @@ -28,6 +28,13 @@ import { renderToolsSdk } from './ts-types.ts' import type { ToolSdkSchema } from './ts-types.ts' import { renderToolsSdkPy } from './py-types.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + /** Tool availability changes supplied by the tool registry. */ + 'tool-registry': { kind: 'tool-registry' } + } +} + /** * Language → SDK-section renderer. The registry looks up the loaded * `ctx.ptcRuntime.language` in this table when assembling the `tools:sdk` @@ -1260,7 +1267,7 @@ export class ToolRuntime extends Service { /** Project one definition onto the model-facing schema fields. */ private schemaOf(definition: ToolDefinition, detachParameters: boolean): ToolSchema { - const { name, description, parameters } = definition + const { name, description, parameters, deferLoading } = definition const detached = detachParameters ? snapshotJsonValue(parameters) : parameters if (detached === undefined) { throw new Error(`tool "${name}" parameters must be lossless JSON before schema projection`) @@ -1269,6 +1276,7 @@ export class ToolRuntime extends Service { name, description, parameters: detached, + ...deferLoading === true ? { deferLoading } : {}, } } diff --git a/packages/core/tools/src/ptc.ts b/packages/core/tools/src/ptc.ts index 7c7a80c6fe..eadfbaabcc 100644 --- a/packages/core/tools/src/ptc.ts +++ b/packages/core/tools/src/ptc.ts @@ -8,6 +8,13 @@ import { brandString } from '@deepseek-ai/dsh-brand' import { createUserMessage, HarnessError } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + /** Images deferred from a successful PTC subcall's final result. */ + 'ptc-mode': { kind: 'ptc-mode' } + } +} + import type { ContentBlock, ToolCallId, ToolSchema } from '@deepseek-ai/dsh-llm' import type { PtcBindingFunction, PtcRunResult, PtcRunSandbox, PtcRuntime } from '@deepseek-ai/dsh-ptc-runtime' import { approveEscalation, ESCALATION_TARGETS, validateEscalationArgs } from '@deepseek-ai/dsh-sandbox' @@ -632,7 +639,7 @@ export function createRunCodeTool(registry: ToolRuntime, options: RunCodeBridgeO if (!result.isError && result.content.some(block => block.type === 'image')) { exec.deferContext(createUserMessage({ content: result.content, - source: { kind: 'plugin', plugin: 'tools-ptc' }, + source: { kind: 'ptc-mode' }, })) } for (const context of result.additionalContexts ?? []) { diff --git a/packages/core/tools/src/schema.ts b/packages/core/tools/src/schema.ts index 35b4106cd2..54c2aa90b5 100644 --- a/packages/core/tools/src/schema.ts +++ b/packages/core/tools/src/schema.ts @@ -496,6 +496,8 @@ export interface DefineToolOptions, value: InferValue>): JsonValue } + /** Requests deferred loading of the tool definition; see {@link @deepseek-ai/dsh-llm#ToolSchema.deferLoading}. */ + readonly deferLoading?: true /** Optional positive cooperative timeout budget in milliseconds. */ readonly timeoutMs?: number /** @@ -581,6 +583,7 @@ export function defineTool { const violations = validate(args) diff --git a/packages/core/tools/tests/ptc.spec.ts b/packages/core/tools/tests/ptc.spec.ts index a4bf2e2182..2436c16e5a 100644 --- a/packages/core/tools/tests/ptc.spec.ts +++ b/packages/core/tools/tests/ptc.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import type { ToolSchema } from '@deepseek-ai/dsh-llm' import { createScope } from '@deepseek-ai/dsh-scope' import type { Scope } from '@deepseek-ai/dsh-scope' @@ -17,6 +18,13 @@ import type { JsonValue } from '@deepseek-ai/dsh-util-values' import SandboxPolicy from '@deepseek-ai/dsh-sandbox-policy' import SessionProjections from '@deepseek-ai/dsh-session-projection' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'order-probe': { kind: 'order-probe' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal /** @@ -818,7 +826,7 @@ describe('the sub-dispatch scheduler (native concurrency contract)', () => { kind: 'accept' as const, additionalContexts: [createUserMessage({ content: [{ type: 'text' as const, text: `ctx:${String(postExec.callId)}` }], - source: { kind: 'plugin' as const, plugin: 'order-probe' }, + source: { kind: 'order-probe' as const }, })], } } @@ -1322,7 +1330,7 @@ describe('the run_code dispatch bridge', () => { kind: 'accept' as const, additionalContexts: [createUserMessage({ content: [{ type: 'text' as const, text: `context for ${exec.callId}` }], - source: { kind: 'plugin' as const, plugin: 'test' }, + source: { kind: 'test' as const }, })], }) } @@ -1339,12 +1347,12 @@ describe('the run_code dispatch bridge', () => { { role: 'user', content: [{ type: 'text', text: 'context for call-1:ptc:1' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }, { role: 'user', content: [{ type: 'text', text: 'context for call-1:ptc:2' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }, ]) }) @@ -1375,7 +1383,7 @@ describe('the run_code dispatch bridge', () => { expect(result.additionalContexts).toMatchObject([{ role: 'user', - source: { kind: 'plugin', plugin: 'tools-ptc' }, + source: { kind: 'ptc-mode' }, content: [ { type: 'text', text: 'image result' }, { type: 'image', attachment: { mediaType: 'image/png', bytes: 1, width: 1, height: 1 } }, @@ -1425,7 +1433,7 @@ describe('the run_code dispatch bridge', () => { kind: 'accept', additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'nested context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], }) }) @@ -1441,7 +1449,7 @@ describe('the run_code dispatch bridge', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'nested context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }]) }) diff --git a/packages/core/tools/tests/tools.spec.ts b/packages/core/tools/tests/tools.spec.ts index 6caf233ce9..2d94a9a95a 100644 --- a/packages/core/tools/tests/tools.spec.ts +++ b/packages/core/tools/tests/tools.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, expectTypeOf, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import LlmRuntime, { createUserMessage, ToolCallId, HarnessError, type ContentBlock } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' @@ -15,6 +16,19 @@ import ToolRuntime, { } from '@deepseek-ai/dsh-tools' import type { JsonValue } from '@deepseek-ai/dsh-util-values' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'blocker': { kind: 'blocker' } & ContextFormed + 'child': { kind: 'child' } & ContextFormed + 'nested': { kind: 'nested' } & ContextFormed + 'nested-1': { kind: 'nested-1' } & ContextFormed + 'nested-2': { kind: 'nested-2' } & ContextFormed + 'post': { kind: 'post' } & ContextFormed + 'test': { kind: 'test' } & ContextFormed + 'wrapper': { kind: 'wrapper' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal async function setup() { @@ -38,6 +52,17 @@ const echoTool = defineTool({ }) describe('ToolRuntime', () => { + it('preserves deferred loading through registry and prompt schema projection', async () => { + const ctx = await setup() + try { + ctx.tools.register(defineContentToolFixture({ name: 'deferred', description: '', parameters: {}, deferLoading: true, async execute() { return [] } })) + expect(ctx.tools.schemas()[0]?.deferLoading).toBe(true) + expect((await ctx.systemPrompt.assemble()).tools[0]?.deferLoading).toBe(true) + } finally { + await ctx.fiber.dispose() + } + }) + it('registers tools, exposes schemas, and feeds the system-prompt assembly', async () => { const ctx = await setup() ctx.tools.register(echoTool) @@ -369,7 +394,7 @@ describe('ToolRuntime', () => { kind: 'accept', value: { text: 'policy value' }, additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'value context' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'value context' }], source: { kind: 'test' }, })], } }) @@ -393,7 +418,7 @@ describe('ToolRuntime', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'value context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }], }) }) @@ -517,7 +542,7 @@ describe('ToolRuntime', () => { content: [{ type: 'text', text: 'wrapper content' }], meta: { wrapped: true }, additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'wrapper context' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'wrapper context' }], source: { kind: 'test' }, })], })) @@ -531,7 +556,7 @@ describe('ToolRuntime', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'wrapper context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }], }) }) @@ -951,14 +976,14 @@ describe('ToolRuntime', () => { kind: 'block', feedback: [{ type: 'text', text: 'rejected' }], additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'why it was rejected' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'why it was rejected' }], source: { kind: 'test' }, })], })) const result = await ctx.tools.execute({ signal: testToolSignal, callId: ToolCallId('c1'), name: 'echo', arguments: { text: 'hi' } }) expect(result.isError).toBe(true) expect(result.content[0]).toMatchObject({ text: 'rejected' }) - expect(result.additionalContexts).toMatchObject([{ content: [{ text: 'why it was rejected' }], source: { kind: 'plugin', plugin: 'test' } }]) + expect(result.additionalContexts).toMatchObject([{ content: [{ text: 'why it was rejected' }], source: { kind: 'test' } }]) }) it('post-execute additionalContexts ride on the result for the loop to buffer', async () => { @@ -967,11 +992,11 @@ describe('ToolRuntime', () => { ctx.on('tools/post-execute', async (_exec, _result, _next): Promise => ({ kind: 'accept', additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'fyi' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'fyi' }], source: { kind: 'test' }, })] })) const result = await ctx.tools.execute({ signal: testToolSignal, callId: ToolCallId('c1'), name: 'echo', arguments: { text: 'hi' } }) - expect(result.additionalContexts).toMatchObject([{ content: [{ text: 'fyi' }], source: { kind: 'plugin', plugin: 'test' } }]) + expect(result.additionalContexts).toMatchObject([{ content: [{ text: 'fyi' }], source: { kind: 'test' } }]) }) it('preserves tool-deferred, execute-wrapper, and post-execute contexts in order', async () => { @@ -982,10 +1007,10 @@ describe('ToolRuntime', () => { parameters: {}, async execute(_args, exec) { exec.deferContext(createUserMessage({ - content: [{ type: 'text', text: 'nested-1' }], source: { kind: 'plugin', plugin: 'nested-1' }, + content: [{ type: 'text', text: 'nested-1' }], source: { kind: 'nested-1' }, })) exec.deferContext(createUserMessage({ - content: [{ type: 'text', text: 'nested-2' }], source: { kind: 'plugin', plugin: 'nested-2' }, + content: [{ type: 'text', text: 'nested-2' }], source: { kind: 'nested-2' }, })) return [{ type: 'text', text: 'done' }] }, @@ -997,7 +1022,7 @@ describe('ToolRuntime', () => { additionalContexts: [ ...result.additionalContexts ?? [], createUserMessage({ - content: [{ type: 'text', text: 'wrapper' }], source: { kind: 'plugin', plugin: 'wrapper' }, + content: [{ type: 'text', text: 'wrapper' }], source: { kind: 'wrapper' }, }), ], } @@ -1008,7 +1033,7 @@ describe('ToolRuntime', () => { ...downstream, additionalContexts: [ createUserMessage({ - content: [{ type: 'text', text: 'post' }], source: { kind: 'plugin', plugin: 'post' }, + content: [{ type: 'text', text: 'post' }], source: { kind: 'post' }, }), ...downstream.additionalContexts ?? [], ], @@ -1018,10 +1043,10 @@ describe('ToolRuntime', () => { const result = await ctx.tools.execute({ signal: testToolSignal, callId: ToolCallId('composite'), name: 'composite', arguments: {} }) expect(result.additionalContexts?.map(context => context.source)).toEqual([ - { kind: 'plugin', plugin: 'nested-1' }, - { kind: 'plugin', plugin: 'nested-2' }, - { kind: 'plugin', plugin: 'wrapper' }, - { kind: 'plugin', plugin: 'post' }, + { kind: 'nested-1' }, + { kind: 'nested-2' }, + { kind: 'wrapper' }, + { kind: 'post' }, ]) }) @@ -1033,7 +1058,7 @@ describe('ToolRuntime', () => { parameters: {}, async execute(_args, exec) { exec.deferContext(createUserMessage({ - content: [{ type: 'text', text: 'nested' }], source: { kind: 'plugin', plugin: 'nested' }, + content: [{ type: 'text', text: 'nested' }], source: { kind: 'nested' }, })) throw new Error('outer failure') }, @@ -1041,18 +1066,18 @@ describe('ToolRuntime', () => { const failed = await ctx.tools.execute({ signal: testToolSignal, callId: ToolCallId('failed'), name: 'failing-composite', arguments: {} }) expect(failed.isError).toBe(true) - expect(failed.additionalContexts?.map(context => context.source)).toEqual([{ kind: 'plugin', plugin: 'nested' }]) + expect(failed.additionalContexts?.map(context => context.source)).toEqual([{ kind: 'nested' }]) ctx.on('tools/post-execute', async (): Promise => ({ kind: 'block', feedback: [{ type: 'text', text: 'blocked' }], additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'block-only' }], source: { kind: 'plugin', plugin: 'blocker' }, + content: [{ type: 'text', text: 'block-only' }], source: { kind: 'blocker' }, })], })) const blocked = await ctx.tools.execute({ signal: testToolSignal, callId: ToolCallId('blocked'), name: 'failing-composite', arguments: {} }) expect(blocked.isError).toBe(true) - expect(blocked.additionalContexts?.map(context => context.source)).toEqual([{ kind: 'plugin', plugin: 'blocker' }]) + expect(blocked.additionalContexts?.map(context => context.source)).toEqual([{ kind: 'blocker' }]) }) it('composes pre + post waterfalls around dispatch (sandbox-wrap pattern)', async () => { @@ -1317,7 +1342,7 @@ describe('ToolRuntime', () => { isError: false, additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'wrapper context' }], - source: { kind: 'plugin', plugin: 'wrapper' }, + source: { kind: 'wrapper' }, })], } }) @@ -1337,7 +1362,7 @@ describe('ToolRuntime', () => { content: [{ type: 'text', text: 'Error: tool call aborted before dispatch' }], isError: true, error: { info: { name: 'AbortError', code: TOOL_ABORTED_BEFORE_DISPATCH } }, - additionalContexts: [{ source: { kind: 'plugin', plugin: 'wrapper' } }], + additionalContexts: [{ source: { kind: 'wrapper' } }], }) expect(dispatched).toBe(0) }) @@ -1350,7 +1375,7 @@ describe('ToolRuntime', () => { async execute(_args, exec) { exec.deferContext(createUserMessage({ content: [{ type: 'text', text: 'completed child work' }], - source: { kind: 'plugin', plugin: 'child' }, + source: { kind: 'child' }, })) return 'body complete' }, @@ -1375,7 +1400,7 @@ describe('ToolRuntime', () => { content: [{ type: 'text', text: 'Error: tool call aborted' }], isError: true, error: { info: { name: 'AbortError', code: TOOL_ABORTED } }, - additionalContexts: [{ source: { kind: 'plugin', plugin: 'child' } }], + additionalContexts: [{ source: { kind: 'child' } }], }) }) @@ -1387,7 +1412,7 @@ describe('ToolRuntime', () => { async execute(_args, exec) { exec.deferContext(createUserMessage({ content: [{ type: 'text', text: 'completed child work' }], - source: { kind: 'plugin', plugin: 'child' }, + source: { kind: 'child' }, })) return 'body complete' }, @@ -1402,7 +1427,7 @@ describe('ToolRuntime', () => { ...decision, additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'post context' }], - source: { kind: 'plugin', plugin: 'post' }, + source: { kind: 'post' }, })], } }) @@ -1419,8 +1444,8 @@ describe('ToolRuntime', () => { isError: true, error: { info: { name: 'AbortError', code: TOOL_ABORTED } }, additionalContexts: [ - { source: { kind: 'plugin', plugin: 'child' } }, - { source: { kind: 'plugin', plugin: 'post' } }, + { source: { kind: 'child' } }, + { source: { kind: 'post' } }, ], }) }) @@ -1592,7 +1617,7 @@ describe('ToolRuntime', () => { execute(_args, exec) { exec.deferContext(createUserMessage({ content: [{ type: 'text', text: 'nested outcome' }], - source: { kind: 'plugin', plugin: 'nested' }, + source: { kind: 'nested' }, })) entered.resolve(undefined) return release.promise @@ -1614,7 +1639,7 @@ describe('ToolRuntime', () => { await expect(pending).resolves.toMatchObject({ isError: true, error: { info: { name: 'AbortError', code: TOOL_ABORTED } }, - additionalContexts: [{ source: { kind: 'plugin', plugin: 'nested' } }], + additionalContexts: [{ source: { kind: 'nested' } }], }) }) @@ -1882,7 +1907,7 @@ describe('ToolRuntime', () => { value: 'short-circuited with context', additionalContexts: [createUserMessage({ content: [{ type: 'text', text: 'from around dispatch' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })) @@ -1894,7 +1919,7 @@ describe('ToolRuntime', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'from around dispatch' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }]) }) diff --git a/packages/experimental/agent-team/README.i18n.yaml b/packages/experimental/agent-team/README.i18n.yaml index 47dbb4329a..74dbfe69df 100644 --- a/packages/experimental/agent-team/README.i18n.yaml +++ b/packages/experimental/agent-team/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/experimental/agent-team/README.md -README.md: 6e2b55018971ec96802de0e5be042d49b45c674a -README.zh.md: b497d3790e43a9bc843e2a6b88c9755b698034b5 +README.md: 31ea956d2e39dfe25410929be2a574b4c3f07a7d +README.zh.md: 03344285ceaee965c4154f939f22b592c833840b diff --git a/packages/experimental/agent-team/README.md b/packages/experimental/agent-team/README.md index 6e2b550189..31ea956d2e 100644 --- a/packages/experimental/agent-team/README.md +++ b/packages/experimental/agent-team/README.md @@ -145,6 +145,8 @@ Tasks are complete versioned snapshots; every mutation carries `expectedRevision Team events are appended to the exact live Lead Session and flushed before the operation reports success or wakes waiters. `team/member`, `team/task`, `team/message/queued`, and `team/message/delivered` are log-only: they never enter the conversation surface, so derived model history is untouched by coordination records. Session event `seq` and `time` own ordering and timing; snapshots do not duplicate them. The `./invariant` companion replays each candidate Team event against its committed prefix and rejects invalid transitions before append. +Native V4 Team event and checkpoint admission reject retired `tool-result` content before it can enter mailbox state. Historical conversion belongs to the Session-format migration; the Team projection does not convert old wrappers. + ### Disposal Disposal closes admission, aborts and awaits admitted creation and mailbox-dispatch transactions, then asks the continuation owner to release the roster's exact live direct children and their descendants; non-Team continuable children of the Lead remain untouched. Cleanup failures make disposal fail visibly, bounded by `disposalTimeoutMs`. diff --git a/packages/experimental/agent-team/README.zh.md b/packages/experimental/agent-team/README.zh.md index b497d3790e..03344285ce 100644 --- a/packages/experimental/agent-team/README.zh.md +++ b/packages/experimental/agent-team/README.zh.md @@ -145,6 +145,8 @@ Lead 可以停止 teammate 的当前轮次,而不会删除其排队的消息 Team 事件追加到精确的 live Lead 会话,并在操作报告成功或唤醒等待者之前 flush。`team/member`、`team/task`、`team/message/queued` 与 `team/message/delivered` 仅存在于日志:它们从不进入会话表面,因此派生模型历史不受协作记录影响。顺序与时间由会话事件的 `seq` 与 `time` 负责,快照不重复保存。`./invariant` 伴生插件把每条候选 Team 事件对照已提交前缀回放,并在 append 前拒绝非法转换。 +原生 V4 的 Team 事件及检查点准入会拒绝退役的 `tool-result` 内容,防止它进入邮箱状态。历史转换由 Session 格式迁移负责,Team 投影不转换旧包装。 + ### Dispose dispose 会关闭准入、中止并等待已获准的创建与 mailbox dispatch 事务,再让 continuation owner 释放 roster 中确切的 live direct child 及其后代;Lead 的非 Team continuable child 不受影响。cleanup 失败会让 dispose 明确失败,并以 `disposalTimeoutMs` 为上限。 diff --git a/packages/experimental/agent-team/src/projection.ts b/packages/experimental/agent-team/src/projection.ts index 85fdfd0e0d..d5dff9784c 100644 --- a/packages/experimental/agent-team/src/projection.ts +++ b/packages/experimental/agent-team/src/projection.ts @@ -40,8 +40,8 @@ const imageAttachmentSchema = z.object({ name: z.string().optional(), }).strict() -// ContentBlockMap is merge-extensible. Validate every core variant exactly, -// while retaining JSON-decoded plugin variants under an unknown type tag. +// Validate the listed variants; retired tool-result tags cannot enter the +// merge-extensible fallback for JSON-decoded plugin content. const contentBlockSchema: z.ZodType = z.lazy(() => z.union([ z.object({ type: z.literal('text'), text: z.string() }).strict(), z.object({ type: z.literal('reasoning'), text: z.string() }).strict(), @@ -52,12 +52,6 @@ const contentBlockSchema: z.ZodType = z.lazy(() => z.union([ name: z.string(), arguments: z.string(), }).strict(), - z.object({ - type: z.literal('tool-result'), - toolCallId: z.string().min(1), - content: z.array(contentBlockSchema), - isError: z.boolean().optional(), - }).strict(), z.object({ type: z.string().min(1) }).loose().refine( block => !coreContentBlockTypes.has(block.type), { message: 'known content block types must match their declared fields' }, diff --git a/packages/experimental/agent-team/tests/projection-events.spec.ts b/packages/experimental/agent-team/tests/projection-events.spec.ts index 5f9728a979..e5443d4135 100644 --- a/packages/experimental/agent-team/tests/projection-events.spec.ts +++ b/packages/experimental/agent-team/tests/projection-events.spec.ts @@ -1,6 +1,8 @@ -import { describe, expect, it } from 'vitest' -import { SESSION_FORMAT_VERSION, SessionId, SessionSeq } from '@deepseek-ai/dsh-session' +import { describe, expect, it, onTestFinished } from 'vitest' +import { Context } from '@deepseek-ai/cordis' +import SessionStore, { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionEventMap, SessionEventType } from '@deepseek-ai/dsh-session' +import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { teamProjectionDefinition } from '../src/projection.ts' import type { TeamProjectionState, TeamState } from '../src/projection.ts' import { TeamId, TeamMessageId, TeamTaskId } from '../src/types.ts' @@ -82,6 +84,28 @@ function message(overrides: Partial = {}): TeamMessageSnaps } describe('Agent Teams projection events', () => { + it('rejects retired tool-result content when restoring a native V4 Team checkpoint', async () => { + const ctx = new Context() + onTestFinished(() => ctx.fiber.dispose()) + await ctx.plugin(SessionStore) + await ctx.plugin(SessionProjectionRegistry) + ctx.effect(() => ctx.sessionProjections.register(teamProjectionDefinition)) + const session = ctx.sessions.create(ROOT) + const restore = (val: unknown) => ctx.sessionProjections.restore({ + agentTeam: { ver: teamProjectionDefinition.stateVersion, seq: -1, val }, + }, [], SessionLogOffset(0), session.header, SessionLogOffset(0)) + const valid = { ...project(ROOT, []), messages: [message()] } + expect(restore(JSON.parse(JSON.stringify(valid))).checkpoint['agentTeam']?.val).toEqual(valid) + const retiredMessage = message({ content: [{ + type: 'tool-result', toolCallId: 'retired', content: [{ type: 'text', text: 'old result' }], + }] as unknown as TeamMessageSnapshot['content'] }) + const retired = { ...valid, messages: [retiredMessage] } + expect(() => restore(JSON.parse(JSON.stringify(retired)))).toThrow() + expect(() => projectTeam(ROOT, [event('team/message/queued', { + version: 2, teamId: TEAM, message: retiredMessage, + }, SessionSeq(0))])).toThrow(/team\/message\/queued payload is invalid/) + }) + it('projects current-team records independently from inherited records', () => { const records: SessionEvent[] = [ event('team/member', { version: 2, teamId: TeamId('ancestor'), member: member() }, SessionSeq(0)), diff --git a/packages/experimental/auto-review/README.i18n.yaml b/packages/experimental/auto-review/README.i18n.yaml index 654d67557a..c35679716a 100644 --- a/packages/experimental/auto-review/README.i18n.yaml +++ b/packages/experimental/auto-review/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/experimental/auto-review/README.md -README.md: db4d1d3c5a8ace23f41b3d522824b3163156fc7a -README.zh.md: c4fd7e59b25f22adb4b1947fc0b27ff844c3ebf2 +README.md: 73ee9e5aaff00f1160f647218b5714b63c23684b +README.zh.md: 40fe6f48cae4854c5cfd5ea8f3ae4276dd540e82 diff --git a/packages/experimental/auto-review/README.md b/packages/experimental/auto-review/README.md index db4d1d3c5a..73ee9e5aaf 100644 --- a/packages/experimental/auto-review/README.md +++ b/packages/experimental/auto-review/README.md @@ -57,7 +57,7 @@ A denied call uses the ordinary tool card. The collapsed row identifies Auto rev [`cordis.patch.yml`](cordis.patch.yml) inserts the package itself as the `auto-review` row. [`src/index.ts`](src/index.ts) requires the LLM, permission, Session, and tools services, then installs the preset contribution and prepended pre-execute listener in one effect. The [permission owner](../../interaction/permission-presets/README.md) supplies the current identity and process catalog; Auto shares Full access's existing sandbox and approval values without changing tool definitions. -The reviewer reconstructs five sections from the current Session surface and pending execution: fixed policy, cwd-only environment, sourced project constraints, filtered sourced history, and the complete pending action. Native schema comes from the latest request header. A PTC binding freezes its schema and carries it through the scheduler into transient execution metadata; start and settle events never serialize description or parameters. Main-agent `system/message` nodes, assistant text and reasoning, and tool results are excluded. [The decision record](../../../.agents/notes/implemented/feature/2026-08-28-auto-review.md) owns authority, lifecycle, and child-inheritance rationale. +The reviewer reconstructs five sections from the current Session surface and pending execution: fixed policy, cwd-only environment, sourced project constraints, filtered sourced history, and the complete pending action. Native schema comes from the latest request header. A PTC binding freezes its schema and carries it through the scheduler into transient execution metadata; start and settle events never serialize description or parameters. Main-agent `system/message` nodes, assistant text and reasoning, and tool results are excluded. The outer review input is a frozen `RequestUserInput` without durable identity or source; retained history keeps its original source attribution in the review text. [The decision record](../../../.agents/notes/implemented/feature/2026-08-28-auto-review.md) owns authority, lifecycle, and child-inheritance rationale. Unloading closes selection and review admission, migrates live Auto Sessions to Full access through the existing preset writer, then aborts and drains reviews before withdrawing the listener and contribution. Knobs and persistent terminals survive that migration. A persisted Auto Session cannot publish without the complete integration; reopening it after installation is an explicit user action. Reinstalling the layer restores the option but does not switch live Sessions back to Auto. diff --git a/packages/experimental/auto-review/README.zh.md b/packages/experimental/auto-review/README.zh.md index c4fd7e59b2..40fe6f48ca 100644 --- a/packages/experimental/auto-review/README.zh.md +++ b/packages/experimental/auto-review/README.zh.md @@ -57,7 +57,7 @@ Auto 在每个受支持调用的 body 执行前审查一次,包括每个已开 [`cordis.patch.yml`](cordis.patch.yml)把本包自身插入为 `auto-review` 行。[`src/index.ts`](src/index.ts)要求 LLM、permission、Session 与 tools 服务,然后在同一个 effect 中安装 preset contribution 和置前的 pre-execute listener。[权限 owner](../../interaction/permission-presets/README.zh.md)提供当前身份和进程目录;Auto 共用 Full access 既有沙箱与审批值,不改变工具定义。 -Reviewer 从当前 Session surface 与待执行调用重建五个分区:固定策略、仅 cwd 的环境、带来源的项目约束、过滤后带来源的历史,以及完整待审动作。原生 schema 来自最新 request header。PTC binding 冻结其 schema,经由调度器传入临时执行元数据;开始与结算事件都不序列化描述或参数 schema。主 agent 的 `system/message` 节点、assistant 正文与 reasoning、tool results 全部排除。[决策记录](../../../.agents/notes/implemented/feature/2026-08-28-auto-review.zh.md)拥有权威、生命周期与 child 继承的理由。 +Reviewer 从当前 Session surface 与待执行调用重建五个分区:固定策略、仅 cwd 的环境、带来源的项目约束、过滤后带来源的历史,以及完整待审动作。原生 schema 来自最新 request header。PTC binding 冻结其 schema,经由调度器传入临时执行元数据;开始与结算事件都不序列化描述或参数 schema。主 agent 的 `system/message` 节点、assistant 正文与 reasoning、tool results 全部排除。外层评审输入是冻结的 `RequestUserInput`,不含持久身份或来源;保留历史在评审文本中仍携带原始来源。[决策记录](../../../.agents/notes/implemented/feature/2026-08-28-auto-review.zh.md)拥有权威、生命周期与 child 继承的理由。 卸载时先关闭选择与 review admission,经由既有 preset writer 将存活 Auto Session 迁移到 Full access,再中止并等待在途 review 结清,最后撤回 listener 与 contribution。旋钮与持久终端在迁移中保持不变。持久 Auto Session 缺少完整 integration 时不能发布;安装后重新打开需要用户显式操作。重装只恢复选项,不把存活 Session 切回 Auto。 diff --git a/packages/experimental/auto-review/src/index.ts b/packages/experimental/auto-review/src/index.ts index 402695b933..14c9f67ff5 100644 --- a/packages/experimental/auto-review/src/index.ts +++ b/packages/experimental/auto-review/src/index.ts @@ -11,7 +11,6 @@ import type { Agent } from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-agent-instructions' import { BlockAssembler, - createUserMessage, type ContentBlock, type GenerateOptions, type MessageSource, @@ -185,7 +184,8 @@ function isProjectInstruction(source: MessageSource): boolean { /** Whether this source is a compaction checkpoint. */ function isCheckpoint(source: MessageSource): boolean { - return source.kind === 'plugin' && source.plugin === 'compact' + const kind: string = source.kind + return kind === 'compact-checkpoint' } /** Whether this message was durably attributed to the child's direct parent. */ @@ -242,8 +242,7 @@ function filteredUserEntries( initialPromptSeq: SessionEvent['seq'] | undefined, parentSession: string | undefined, ): HistoricalUserMessage[] { - const retained = content.filter(block => block.type !== 'tool-result') - return retained.map(block => ({ + return content.map(block => ({ kind: 'user-message', role: block.type === 'text' ? textRole(source, seq, initialPromptSeq, parentSession) @@ -424,7 +423,7 @@ function snapshotAutoReview(agent: Agent, exec: ToolExecution): ReviewSnapshot { if (event.type === 'user/message') { if (event.data.source.kind === 'tool') continue if (isProjectInstruction(event.data.source)) { - const content = event.data.content.filter(block => block.type !== 'tool-result') + const content = event.data.content if (content.length > 0) { projectInstructions.push({ kind: 'user-message', @@ -616,14 +615,15 @@ async function classifyRisk( signal: AbortSignal, ): Promise { const snapshot = snapshotAutoReview(agent, exec) + // This review prompt is sent only through ctx.llm.stream and never enters a Session log. const options: GenerateOptions = deepFreeze({ provider: snapshot.provider, model: snapshot.model, system: REVIEW_POLICY, - messages: [createUserMessage({ + messages: [{ + role: 'user', content: [{ type: 'text', text: reviewUserText(snapshot) }], - source: { kind: 'plugin', plugin: 'dsh-experimental-auto-review' }, - })], + }], temperature: 0, signal, }) diff --git a/packages/experimental/auto-review/tests/auto-review.e2e.ts b/packages/experimental/auto-review/tests/auto-review.e2e.ts index b730bd7c05..69de19fa97 100644 --- a/packages/experimental/auto-review/tests/auto-review.e2e.ts +++ b/packages/experimental/auto-review/tests/auto-review.e2e.ts @@ -171,9 +171,9 @@ function orchestrate(ctx: Context, real: boolean) { return next() }) ctx.on('llm/stream', (options, next) => { - const source = options.messages[0]?.source - if (options.system?.startsWith('REVIEW_POLICY\n') === true - && source?.kind === 'plugin' && source.plugin === 'dsh-experimental-auto-review') { + if (options.system?.startsWith('REVIEW_POLICY\n') === true) { + expect(options.messages[0]).not.toHaveProperty('source') + expect(options.messages[0]).not.toHaveProperty('id') if (expected === undefined || mainAgent === undefined) throw new Error('Unexpected reviewer call outside a case') reviewCalls += 1 expect(options.provider === PROVIDER && options.model === mainAgent.options.model).toBe(true) @@ -227,7 +227,7 @@ function outcome(events: readonly SessionEvent[], path: Path): { denied: boolean const starts = events.filter(event => event.type === 'tool/ptc-dispatch-start') expect(starts).toHaveLength(inner.length) const result = path === 'native' ? native[0]?.data : inner[0]?.data - const isError = path === 'native' ? native[0]?.data.message.content[0]?.isError : inner[0]?.data.isError + const isError = path === 'native' ? native[0]?.data.message.isError : inner[0]?.data.isError return { denied: result?.error?.code === DENIED && isError === true, success: isError === false } } diff --git a/packages/experimental/auto-review/tests/auto-review.spec.ts b/packages/experimental/auto-review/tests/auto-review.spec.ts index 6816d192e4..6007f789b3 100644 --- a/packages/experimental/auto-review/tests/auto-review.spec.ts +++ b/packages/experimental/auto-review/tests/auto-review.spec.ts @@ -278,7 +278,7 @@ describe('native review request', () => { }) appendHeader(session, [loggedSchema]) session.append('system/message', { - turn: 1, step: 1, message: createSystemMessage('main-system secret', 'main'), + turn: 1, step: 1, message: createSystemMessage('main-system secret'), }, { surfaceOp: 'append' }) session.append('user/message', createUserMessage({ content: [ @@ -297,37 +297,15 @@ describe('native review request', () => { } as never) appendUser(session, 'parent-authored evidence', { kind: 'user' }) session.append('user/message', createUserMessage({ - content: [ - { type: 'text', text: 'plugin evidence' }, - { - type: 'tool-result', - toolCallId: ToolCallId('result-source'), - content: [{ type: 'text', text: 'tool result secret' }], - isError: false, - }, - ], - source: { kind: 'plugin', plugin: 'evidence' }, - }), { surfaceOp: 'append' }) - session.append('user/message', createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('result-only-source'), - content: [{ type: 'text', text: 'tool-result-only secret' }], - isError: false, - }], - source: { kind: 'plugin', plugin: 'tool-result-only' }, + content: [{ type: 'text', text: 'plugin evidence' }], + source: { kind: 'test' }, }), { surfaceOp: 'append' }) appendUser(session, 'checkpoint authority', compactCheckpointSource(CompactionId('checkpoint-1'))) appendUser(session, 'project authority', { kind: 'agent-instructions', form: 'instructions', changes: [], }) session.append('user/message', createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('project-result-only'), - content: [{ type: 'text', text: 'project-tool-result-only secret' }], - isError: false, - }], + content: [], source: { kind: 'agent-instructions', form: 'instructions', changes: [] }, }), { surfaceOp: 'append' }) appendUser(session, 'tool-source secret', { kind: 'tool', callId: ToolCallId('result-source') }) @@ -342,6 +320,22 @@ describe('native review request', () => { appendNativeCall(session, oldCallId, 'old_probe', '{ "old": true }') appendNativeCall(session, outerCallId, RUN_CODE_NAME, '{"code":"call probe"}') appendNativeCall(session, currentCallId, 'probe', '{"path":"target"}') + for (const [callId, text] of [ + ['result-source', 'tool result secret'], + ['result-only-source', 'tool-result-only secret'], + ['project-result-only', 'project-tool-result-only secret'], + ] as const) { + appendNativeCall(session, ToolCallId(callId), 'probe', '{"path":"target"}') + session.append('tool/result', { + turn: 1, + step: 1, + message: createToolResultMessage({ + callId: ToolCallId(callId), + content: [{ type: 'text', text }], + isError: false, + }), + }, { surfaceOp: 'append' }) + } session.append('tool/result', { turn: 1, step: 1, @@ -388,7 +382,9 @@ describe('native review request', () => { expect(request.maxTokens).toBeUndefined() expect(request.tools).toBeUndefined() expect(request.messages).toHaveLength(1) - expect(request.messages[0]?.source).toEqual({ kind: 'plugin', plugin: 'dsh-experimental-auto-review' }) + expect(request.messages[0]).not.toHaveProperty('source') + expect(request.messages[0]).not.toHaveProperty('id') + expect(Object.isFrozen(request.messages[0]?.content[0])).toBe(true) expect(Object.isFrozen(request)).toBe(true) const sections = requestSections(request) @@ -426,7 +422,7 @@ describe('native review request', () => { source: compactCheckpointSource(CompactionId('checkpoint-1')), }), expect.objectContaining({ - kind: 'user-message', role: 'fact', source: { kind: 'plugin', plugin: 'evidence' }, + kind: 'user-message', role: 'fact', source: { kind: 'test' }, content: [{ type: 'text', text: 'plugin evidence' }], }), expect.objectContaining({ diff --git a/packages/experimental/browser-use-runtime/tests/mcp.spec.ts b/packages/experimental/browser-use-runtime/tests/mcp.spec.ts index ff9426d0aa..18f3cb733b 100644 --- a/packages/experimental/browser-use-runtime/tests/mcp.spec.ts +++ b/packages/experimental/browser-use-runtime/tests/mcp.spec.ts @@ -39,7 +39,7 @@ class FixtureModel extends LlmAdapter { } async * stream(options: GenerateOptions): AsyncIterable { this.requests.push(options) - if (options.tools?.some(tool => tool.name === TOOL) && options.messages.at(-1)?.content[0]?.type === 'text') { + if (options.tools?.some(tool => tool.name === TOOL) && options.messages.at(-1)?.role === 'user') { const call = { type: 'tool-call' as const, id: ToolCallId('visit'), name: TOOL, arguments: '{"label":"fixture"}' } yield { type: 'block-start', index: 0, blockType: 'tool-call' } yield { type: 'tool-call-delta', index: 0, id: call.id, name: call.name, argumentsDelta: call.arguments } diff --git a/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts b/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts index 6891a50d47..253f2dd6a9 100644 --- a/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts +++ b/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts @@ -119,9 +119,7 @@ it('loads browser tools from cordis.yml, logs browser results, and admits the sc expect(JSON.stringify(extraction)).toContain('Fixture heading') const result = events.find(event => event.type === 'tool/result' && event.data.message.source.callId === 'screenshot') if (result?.type !== 'tool/result') throw new Error('Missing screenshot result') - const tool = result.data.message.content[0] - if (tool?.type !== 'tool-result') throw new Error('Missing tool result content') - const image = tool.content.find(block => block.type === 'image') + const image = result.data.message.content.find(block => block.type === 'image') if (image?.type !== 'image') throw new Error('Missing durable screenshot') const stored = await context.attachments.readImage(image.attachment) expect(Buffer.from(stored.data).toString('base64')).toBe(screenshotBase64) diff --git a/packages/experimental/client-ui-agent-team/src/client/mount.ts b/packages/experimental/client-ui-agent-team/src/client/mount.ts index 03a01b7b94..7108c67e8d 100644 --- a/packages/experimental/client-ui-agent-team/src/client/mount.ts +++ b/packages/experimental/client-ui-agent-team/src/client/mount.ts @@ -54,8 +54,11 @@ function registerUi(ctx: ClientContext): void { async openTeammate(sessionId: SessionId, member: TeamRosterMember): Promise { if (member.role !== 'teammate') return const parentSessionId = leadSessionId(sessionId) - await sessions.refreshSubagents(parentSessionId) + await sessions.refreshProjections(parentSessionId) if ((sessions.retainInfo(sessionId).getSnapshot().retainedBy.mainView ?? 0) === 0) return + const catalog = sessions.list.getSnapshot().projectionsBySession[parentSessionId] + const child = catalog?.values.subagentCatalog?.find(entry => entry.id === member.id) + if (child === undefined) return ctx.uiWorkspace.openSession({ parentSessionId, childSessionId: member.id, diff --git a/packages/experimental/client-ui-agent-team/tests/browser-plugin.client.spec.ts b/packages/experimental/client-ui-agent-team/tests/browser-plugin.client.spec.ts index 360839e3dc..5619b5dbd7 100644 --- a/packages/experimental/client-ui-agent-team/tests/browser-plugin.client.spec.ts +++ b/packages/experimental/client-ui-agent-team/tests/browser-plugin.client.spec.ts @@ -25,6 +25,7 @@ async function bench(options: { registrationFailure?: boolean remoteFailure?: 'view' | 'update' refreshGate?: Promise + catalog?: 'missing' | 'empty' } = {}) { const ctx = new Context() const calls: { method: string; args: unknown[] }[] = [] @@ -86,7 +87,16 @@ async function bench(options: { }) const navigation: unknown[] = [] let mainSessionId = options.addressed === true ? CHILD : SESSION + const projectionsBySession = options.catalog === 'missing' + ? {} + : { + [SESSION]: { state: 'ready' as const, error: null, values: { subagentCatalog: options.catalog === 'empty' ? [] : [{ createdAt: 1, id: CHILD, + mode: 'continuable' as const, + label: 'worker' as const, + }] } }, + } ctx.provide('sessions', { + list: { getSnapshot: () => ({ projectionsBySession }) }, binding: (id: SessionId) => options.addressed === true && id === CHILD ? { session: { getSnapshot: () => ({ subagent: { @@ -98,7 +108,7 @@ async function bench(options: { }, }) } } : undefined, - refreshSubagents: (id: SessionId) => { + refreshProjections: (id: SessionId) => { navigation.push(['refresh', id]) return options.refreshGate ?? Promise.resolve() }, @@ -289,6 +299,22 @@ describe('ui-team browser plugin', () => { expect(b.navigation).toEqual([['refresh', SESSION]]) }) + it('does not open a teammate missing from the parent catalog', async () => { + for (const catalog of ['missing', 'empty'] as const) { + const b = await bench({ catalog }) + const actions = (b.entry()!.inject as unknown as () => TeamActionInjected)() + await actions.openTeammate(SESSION, { + id: CHILD, + name: 'worker', + role: 'teammate', + status: 'inactive', + diagnostics: [], + }) + expect(b.navigation).toEqual([['refresh', SESSION]]) + await b.fiber.dispose() + } + }) + it('re-registers after the conversation header slot is collapsed and declared again', async () => { const b = await bench() expect(b.entry()).toBeDefined() diff --git a/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts b/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts index 1d23e0417b..b904d88429 100644 --- a/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts +++ b/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts @@ -145,11 +145,9 @@ describe('installed Cua Driver Loader composition', () => { parameters: { type: 'object', properties: { display: { type: 'integer', minimum: 0 } }, required: ['display'], additionalProperties: false }, }) const result = agent.session.snapshotEvents().find(event => event.type === 'tool/result') - expect(result?.data).toMatchObject({ message: { content: [{ type: 'tool-result', content: [{ type: 'text', text: 'Display 0' }, { type: 'image' }] }] } }) + expect(result?.data).toMatchObject({ message: { content: [{ type: 'text', text: 'Display 0' }, { type: 'image' }] } }) if (result?.type !== 'tool/result') throw new Error('Missing durable screenshot result') - const toolResult = result.data.message.content[0] - if (toolResult?.type !== 'tool-result') throw new Error('Missing tool result block') - const image = toolResult.content.find(block => block.type === 'image') + const image = result.data.message.content.find(block => block.type === 'image') if (image?.type !== 'image') throw new Error('Missing durable screenshot image') expect(await ctx.attachments.readImage(image.attachment)).toMatchObject({ ref: { width: 1, height: 1, mediaType: 'image/png' } }) expect(JSON.stringify(agent.session.snapshotEvents())).not.toContain('iVBORw0KGgo') diff --git a/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts b/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts index ead7993a6a..e78af90f9a 100644 --- a/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts +++ b/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts @@ -106,15 +106,16 @@ it('loads from cordis.yml and logs the native screenshot before the next model r expect(JSON.stringify(model.requests[0])).toContain('Cua Driver native computer-use tools operate the host desktop.') const toolEvent = agent.session.snapshotEvents().find(event => event.type === 'tool/result') expect(toolEvent?.data.message.source.callId).toBe('native-window') - const toolResult = agent.session.deriveMessages().flatMap(message => message.content).find(block => block.type === 'tool-result') - const image = toolResult?.type === 'tool-result' ? toolResult.content.find(block => block.type === 'image') : undefined + const toolResult = agent.session.deriveMessages().find(message => message.role === 'tool') + if (toolResult?.role !== 'tool') throw new Error('Native screenshot result was not admitted') + const image = toolResult.content.find(block => block.type === 'image') expect(image?.type).toBe('image') if (image?.type !== 'image') throw new Error('Native screenshot was not admitted') expect(image.attachment).toMatchObject({ mediaType: 'image/png', width: 1, height: 1 }) const stored = await context.attachments.readImage(image.attachment) expect(Buffer.from(stored.data).toString('base64')).toBe(screenshotBase64) expect(JSON.stringify(model.requests[1]?.messages)).toContain(JSON.stringify(image.attachment)) - expect(JSON.stringify(toolResult?.content)).not.toContain(screenshotBase64) + expect(JSON.stringify(toolResult.content)).not.toContain(screenshotBase64) const direct = await context.tools.execute({ agent, signal: new AbortController().signal, callId: ToolCallId('programmatic-window'), name: 'cua_driver_native__get_window_state', arguments: { pid: 9, window_id: 7 }, diff --git a/packages/experimental/tool-agent-team/tests/tool-team.spec.ts b/packages/experimental/tool-agent-team/tests/tool-team.spec.ts index 09025f208a..2c1f188bc2 100644 --- a/packages/experimental/tool-agent-team/tests/tool-team.spec.ts +++ b/packages/experimental/tool-agent-team/tests/tool-team.spec.ts @@ -357,7 +357,7 @@ describe('dsh-tool-team', () => { if (identity === undefined) throw new Error('expected initial teammate reminder') agent.session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'Compacted earlier context.' }], - source: { kind: 'plugin', plugin: 'test-compaction' }, + source: { kind: 'test-compaction' }, }), { surfaceOp: { op: 'replace', startSeq: identity.seq, endSeq: identity.seq }, sourceEventSeqs: [identity.seq], @@ -379,7 +379,7 @@ describe('dsh-tool-team', () => { await using persisted = await ctx.sessionPersistence.open(childId, 'read') const { events } = await persisted.read() expect(events.filter(event => event.type === 'user/message' - && event.data.source.kind === 'plugin' && event.data.source.plugin === toolTeam.name)).toHaveLength(0) + && (event.data.source as { readonly kind?: unknown }).kind === toolTeam.name)).toHaveLength(0) }) it.each(['reject', 'empty', 'abort'] as const)('does not revive a teammate step after %s', async (mode) => { @@ -664,18 +664,27 @@ describe('dsh-tool-team', () => { }) it('reinstalls Team scope before a cold-resumed teammate request', async () => { - const { ctx, lead, adapter } = await setup([textResponse('first'), 'hang', 'hang']) + const { ctx, lead, adapter } = await setup([textResponse('first'), textResponse('lead received settlement'), 'hang']) const spawned = await execute(ctx, lead, 'spawn_teammate', { name: 'cold-worker', description: 'cold worker', prompt: 'finish once', }) const childId = spawnedChildId(ctx, lead, spawned) await vi.waitFor(() => { expect(ctx.agents.get(childId)).toBeUndefined() }, { timeout: 5_000 }) + expect(await ctx.subagents.listChildren(lead.id)).toContainEqual(expect.objectContaining({ + id: childId, + mode: 'continuable', + })) + await vi.waitFor(() => { + expect(adapter.requests.filter(request => request.sessionId === lead.id)).toHaveLength(1) + }) + await lead.whenIdle() - await ctx.agentTeams.sendMessage(lead, { + const receipt = await ctx.agentTeams.sendMessage(lead, { target: 'cold-worker', content: [{ type: 'text', text: 'resume with Team scope' }], signal: SIGNAL, }) + expect(receipt.status).toBe('accepted') const resumed = await waitRunning(ctx, childId) expect((await assembly(ctx, resumed)).tools.map(schema => schema.name) .filter(name => TOOL_NAMES.includes(name)).sort()).toEqual(TOOL_NAMES) diff --git a/packages/experimental/webworker-packer/README.i18n.yaml b/packages/experimental/webworker-packer/README.i18n.yaml index 2707041400..0d9d1a565a 100644 --- a/packages/experimental/webworker-packer/README.i18n.yaml +++ b/packages/experimental/webworker-packer/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/experimental/webworker-packer/README.md -README.md: 90723b7718393ed32005bd6146764044a8ec80b1 -README.zh.md: 9d7df43bf2b49d7b4a0438fcdb96fdbe44cc326a +README.md: c927fd2f4b3bef3078a263f7b65bb0130898ef5b +README.zh.md: 2a10a8c0f51f7596d27b8c2ad92a1eeea6715ca8 diff --git a/packages/experimental/webworker-packer/README.md b/packages/experimental/webworker-packer/README.md index 90723b7718..c927fd2f4b 100644 --- a/packages/experimental/webworker-packer/README.md +++ b/packages/experimental/webworker-packer/README.md @@ -35,7 +35,9 @@ The pack is a three-layer standard stack: `repository.ts` owns the repo-shaped inputs (workspace scan of `vendor/`, `packages/`, `native/system/packages/`, and `apps/`; profile composition through the real CLI dump path); `pack.ts` owns none of them, so the same library packs a different tree by being called differently. The native scan makes the Landlock entry package an ordinary published-view dependency while its executable remains a Worker platform implementation. The CLI is `dsh-pack-vfs-image --out [--profile web]`; `apps/web`'s `build:preview` runs it after the preview shell build. -The repository adapter also declares the preview-only fixture trees under `webworker-runtime/tests/fixtures/`. The CLI packs each named fixture into a separate deterministic overlay archive plus a browser-readable manifest. Overlay files bypass npm publish-view and module-reachability exclusions, so dot directories and example source files remain intact; their mounts are limited to `home/` and `workspace/`. `pack.ts` treats them as opaque bytes, and Session and Workspace interpretation stays in the runtime packages that own those formats. +The repository adapter also declares the preview-only fixture trees under `webworker-runtime/tests/fixtures/`. The CLI packs each named fixture into a separate deterministic overlay archive plus a browser-readable manifest. Overlay files bypass npm publish-view and module-reachability exclusions, so dot directories and example source files remain intact; their mounts are limited to `home/` and `workspace/`. `packVfsOverlay` treats all files as opaque bytes. + +`packPreviewFixture` prepares the newest canonical raw Session generation in each fixture directory through the [Session format catalog](../../session/session-format-catalog/README.md) in Node. It collects direct-child discovery evidence from the same fixture root before completing historical parent catalogs. It strictly restores the source, encodes and strictly validates the current successor, and packs that successor beside unchanged source files. A malformed, unsupported, or future selected generation refuses the build without falling back. Temporary successors are removed after packing. Browser write-open then uses current data without invoking Node's migration-verification Worker. Projection caches remain owner-validated; an older generation cannot supply a current fold checkpoint. ----- @@ -57,6 +59,7 @@ None; this package neither assembles nor sends a provider request. - **Vendored package sources (`src/*.ts`) are excluded** — nothing resolves them at runtime; a future in-worker source-inspection feature would need a dedicated include rule. - **The packer assumes built `lib/` artifacts are current**: it never compiles, so a stale workspace build packs stale bytes. Run the repository build first. - **The CLI requires its original repository location**: `dsh-pack-vfs-image` finds the checkout relative to its own installed file and reads the source CLI, configuration trees, and preview fixtures there. An npm installation supports the parameterized library API; the CLI and repository helpers require a complete, built DeepSeek Harness checkout. +- **Preview Session inputs use raw JSONL** — `packPreviewFixture` rejects compressed and noncanonical Session generation filenames. Generic overlays remain byte-preserving. diff --git a/packages/experimental/webworker-packer/README.zh.md b/packages/experimental/webworker-packer/README.zh.md index 9d7df43bf2..2a10a8c0f5 100644 --- a/packages/experimental/webworker-packer/README.zh.md +++ b/packages/experimental/webworker-packer/README.zh.md @@ -35,7 +35,9 @@ VFS 镜像打包器:把一份合成 profile 变成浏览器 worker 挂载为 `repository.ts` 拥有仓库形态输入(`vendor/`、`packages/`、`native/system/packages/` 与 `apps/` 的 workspace 扫描;经真 CLI dump 路径合成 profile);`pack.ts` 一概不拥有,同一库换参即可打另一棵树。Native 扫描使 Landlock 入口包成为普通发布视图依赖,其可执行文件仍由 Worker 平台实现。CLI 为 `dsh-pack-vfs-image --out [--profile web]`;`apps/web` 的 `build:preview` 在预览壳构建后运行它。 -仓库适配器还声明 `webworker-runtime/tests/fixtures/` 下仅用于 preview 的 fixture(测试前置数据) tree。CLI 会把每套具名 fixture 打成一份独立的确定性 overlay 归档,并写出浏览器可读的 manifest(元数据清单)。Overlay 文件绕过 npm 发布视图和模块可达性排除规则,因此点目录与示例源码会完整保留;其挂载位置仅限 `home/` 与 `workspace/`。`pack.ts` 把它们视为不透明字节;会话与 Workspace 的解释仍归拥有这些格式的运行时包。 +仓库适配器还声明 `webworker-runtime/tests/fixtures/` 下仅用于 preview 的 fixture(测试前置数据) tree。CLI 会把每套具名 fixture 打成一份独立的确定性 overlay 归档,并写出浏览器可读的 manifest(元数据清单)。Overlay 文件绕过 npm 发布视图和模块可达性排除规则,因此点目录与示例源码会完整保留;其挂载位置仅限 `home/` 与 `workspace/`。`packVfsOverlay` 将所有文件视为不透明字节。 + +`packPreviewFixture` 在 Node 中通过 [Session 格式目录](../../session/session-format-catalog/README.zh.md)准备每个 fixture 目录里最新的规范原始 Session 代际。它从同一 fixture 根目录收集直属子 Session 的发现证据,再补全历史父目录。它严格恢复源文件、编码并严格校验当前后继文件,然后将后继文件与未改变的源文件一同打包。如果选中的代际格式错误、不受支持或属于未来版本,构建会拒绝,不回退。临时后继文件在打包后删除。浏览器以写模式打开时即可使用当前数据,无需调用 Node 的迁移校验 Worker。投影缓存仍由其所属包校验;较早代际不能提供当前折叠检查点。 ----- @@ -57,6 +59,7 @@ VFS 镜像打包器:把一份合成 profile 变成浏览器 worker 挂载为 - **vendored 包源码(`src/*.ts`)被排除**——运行时无人解析它们;未来若有 worker 内源码巡检功能需要专门的 include 规则。 - **打包器假定构建产物 `lib/` 是新鲜的**:它从不编译,工作区构建陈旧就会打包陈旧字节。先跑仓库构建。 - **CLI 必须位于原有仓库位置**:`dsh-pack-vfs-image` 相对于自身安装文件定位检出目录,并从中读取源码 CLI、配置树和预览 fixture。npm 安装支持参数化的库 API;CLI 和仓库辅助函数需要完整且已构建的 DeepSeek Harness 检出目录。 +- **Preview Session 输入使用原始 JSONL** — `packPreviewFixture` 拒绝压缩文件与不规范的 Session 代际文件名。通用 overlay 仍逐字节保留输入。 diff --git a/packages/experimental/webworker-packer/package.json b/packages/experimental/webworker-packer/package.json index ae7d6748a0..76ca35e75a 100644 --- a/packages/experimental/webworker-packer/package.json +++ b/packages/experimental/webworker-packer/package.json @@ -36,6 +36,9 @@ "@deepseek-ai/cordis-plugin-include": "workspace:^", "@deepseek-ai/dsh-experimental-webworker-runtime": "workspace:^", "@deepseek-ai/dsh-home-paths": "workspace:^", + "@deepseek-ai/dsh-session-format": "workspace:^", + "@deepseek-ai/dsh-session-format-catalog": "workspace:^", + "@deepseek-ai/dsh-session-format-v3-to-v4": "workspace:^", "js-yaml": "^4.2.0", "picomatch": "^4.0.4" }, diff --git a/packages/experimental/webworker-packer/src/bin.ts b/packages/experimental/webworker-packer/src/bin.ts index 093fac23d5..629fa2a761 100644 --- a/packages/experimental/webworker-packer/src/bin.ts +++ b/packages/experimental/webworker-packer/src/bin.ts @@ -14,9 +14,9 @@ import { PREVIEW_FIXTURE_MANIFEST_FILE, PREVIEW_FIXTURE_MANIFEST_VERSION, type PreviewFixtureManifest, } from '@deepseek-ai/dsh-experimental-webworker-runtime' -import { packVfsImage, packVfsOverlay } from './pack.ts' +import { packVfsImage } from './pack.ts' import { - composeProfile, configTrees, describePack, indexWorkspacePackages, previewFixtures, + composeProfile, configTrees, describePack, indexWorkspacePackages, packPreviewFixture, previewFixtures, } from './repository.ts' /** @@ -66,7 +66,7 @@ const fixtureDirectory = join(dirname(outputFile), 'fixtures') mkdirSync(fixtureDirectory, { recursive: true }) const fixtureLines: string[] = [] const fixtures = fixtureDefinitions.map((fixture) => { - const packed = packVfsOverlay(fixture.trees) + const packed = packPreviewFixture(fixture.trees) const file = `fixtures/${fixture.id}.tar.gz` writeFileSync(join(dirname(outputFile), file), packed.image) fixtureLines.push(` fixture overlay ${fixture.id} (${String(packed.image.byteLength)} B compressed)`) diff --git a/packages/experimental/webworker-packer/src/index.ts b/packages/experimental/webworker-packer/src/index.ts index ea203a6f7a..5ebf1f260e 100644 --- a/packages/experimental/webworker-packer/src/index.ts +++ b/packages/experimental/webworker-packer/src/index.ts @@ -11,6 +11,6 @@ export { type ConfigTree, type ImageTree, type PackOptions, type PackOverlayResult, type PackResult, } from './pack.ts' export { - composeProfile, configTrees, describePack, indexWorkspacePackages, previewFixtures, + composeProfile, configTrees, describePack, indexWorkspacePackages, packPreviewFixture, previewFixtures, type PreviewFixture, } from './repository.ts' diff --git a/packages/experimental/webworker-packer/src/preview.ts b/packages/experimental/webworker-packer/src/preview.ts new file mode 100644 index 0000000000..76f9d86cf2 --- /dev/null +++ b/packages/experimental/webworker-packer/src/preview.ts @@ -0,0 +1,90 @@ +/** Node-side Session preparation for browser Preview data overlays. */ + +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join, posix } from 'node:path' +import { isSessionFormatJsonObject, parseSessionFormatLogFilename, sessionFormatLogFilename } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatCatalogWithChildren, historicalSessionFormatCatalog, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { historicalChildCatalogSource } from '@deepseek-ai/dsh-session-format-v3-to-v4' +import { packVfsOverlay, type ImageTree, type PackOverlayResult } from './pack.ts' +import type { ImageFiles } from './transform-image.ts' + +interface PreviewSession { + readonly path: string + readonly directory: string + readonly id: string + readonly version: number + readonly bytes: Uint8Array +} + +/** + * Pack Preview data with strictly validated current Session successors prepared in Node. + * Committed source bytes remain in the overlay; only the newest canonical raw generation + * of each Session is restored. Future, malformed, and unsupported selected data refuse the pack. + * @param trees - Ordered source trees under the Preview's home and workspace mounts. + * @returns Deterministic overlay containing unchanged inputs and final current successors. + */ +export function packPreviewFixture(trees: readonly ImageTree[]): PackOverlayResult { + const original = packVfsOverlay(trees) + const successors = new Map() + const sources = selectedSessions(original.files).map((source) => { + const text = new TextDecoder('utf-8', { fatal: true }).decode(source.bytes) + if (!text.endsWith('\n')) throw new Error(`preview fixture: ${source.path} has a torn physical tail`) + const [headerLine = '', ...rows] = text.slice(0, -1).split('\n') + const header: unknown = JSON.parse(headerLine) + if (!isSessionFormatJsonObject(header) || header['version'] !== source.version || header['id'] !== source.id) { + throw new Error(`preview fixture: ${source.path} disagrees with its Session header`) + } + const catalog = source.version <= 3 ? historicalSessionFormatCatalog : sessionFormatCatalog + const restore = catalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + const events: unknown[] = rows.map(row => JSON.parse(row) as unknown) + for (const event of events) restore.decodeRow(event) + return { ...source, header, events, artifact: restore.finish() } + }) + for (const source of sources) { + if (source.version === sessionFormatCatalog.currentVersion) continue + const children = sources.filter(child => posix.dirname(child.directory) === posix.dirname(source.directory) + && child.artifact.header.parentSession === source.id && child.artifact.header.origin === 'subagent') + .map(child => ({ ...historicalChildCatalogSource(child.artifact), sourcePath: child.path })) + const restore = createSessionFormatCatalogWithChildren(children).createRestore(source.header, { recovery: 'strict', validation: 'current' }) + for (const event of source.events) restore.decodeRow(event) + const artifact = restore.finish() + const encodedHeader = sessionFormatCatalog.encodeCurrentHeader(artifact.header, artifact.inheritedEventCount) + const encodedEvents = artifact.events.map(event => sessionFormatCatalog.encodeCurrentEvent(event)) + const verification = sessionFormatCatalog.createRestore(encodedHeader, { recovery: 'strict', validation: 'current' }) + for (const event of encodedEvents) verification.decodeRow(event) + verification.finish() + successors.set( + posix.join(source.directory, sessionFormatLogFilename(sessionFormatCatalog.currentVersion)), + [encodedHeader, ...encodedEvents].map(row => JSON.stringify(row) + '\n').join(''), + ) + } + if (successors.size === 0) return original + const directory = mkdtempSync(join(tmpdir(), 'dsh-preview-sessions-')) + try { + for (const [imagePath, content] of successors) { + const path = join(directory, imagePath.slice('home/sessions/'.length)) + mkdirSync(dirname(path), { recursive: true }) + writeFileSync(path, content, { flag: 'wx' }) + } + return packVfsOverlay([...trees, { mount: 'home/sessions', directory }]) + } finally { + rmSync(directory, { recursive: true, force: true }) + } +} + +function selectedSessions(files: ImageFiles): readonly PreviewSession[] { + const selected = new Map() + for (const [path, bytes] of Object.entries(files)) { + const match = /^home\/sessions\/[^/]+\/([^/]+)\/(session(?:\..*)?\.jsonl(?:\.zstd)?)$/u.exec(path) + if (match === null) continue + const version = parseSessionFormatLogFilename(match[2] as string) + if (version === undefined) throw new Error(`preview fixture: ${path} must name a canonical raw Session generation`) + const directory = posix.dirname(path) + const previous = selected.get(directory) + if (previous === undefined || previous.version < version) { + selected.set(directory, { path, directory, id: match[1] as string, version, bytes }) + } + } + return [...selected.values()] +} diff --git a/packages/experimental/webworker-packer/src/repository.ts b/packages/experimental/webworker-packer/src/repository.ts index dd012ba7c7..7314b4d612 100644 --- a/packages/experimental/webworker-packer/src/repository.ts +++ b/packages/experimental/webworker-packer/src/repository.ts @@ -14,6 +14,8 @@ import { join, relative } from 'node:path' import { DSH_HOME_ENV } from '@deepseek-ai/dsh-home-paths' import type { ConfigTree, ImageTree, PackResult } from './pack.ts' +export { packPreviewFixture } from './preview.ts' + /** * Repository directories scanned for workspace and vendored packages. The * image only ever materializes runtime packages, which live here. The Landlock diff --git a/packages/experimental/webworker-packer/tests/built-lib.e2e.ts b/packages/experimental/webworker-packer/tests/built-lib.e2e.ts index 9d74a12682..87ed0e83f1 100644 --- a/packages/experimental/webworker-packer/tests/built-lib.e2e.ts +++ b/packages/experimental/webworker-packer/tests/built-lib.e2e.ts @@ -76,6 +76,7 @@ it('loads both tarballs through plain Node and mounts their base image and overl import * as packer from '@deepseek-ai/dsh-experimental-webworker-packer' import * as runtime from '@deepseek-ai/dsh-experimental-webworker-runtime' import * as client from '@deepseek-ai/dsh-experimental-webworker-runtime/client' + import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' for (const name of ['webworker-packer', 'webworker-runtime']) { assert.equal(import.meta.resolve('@deepseek-ai/dsh-experimental-' + name), new URL('./node_modules/@deepseek-ai/dsh-experimental-' + name + '/lib/index.js', import.meta.url).href) @@ -93,6 +94,14 @@ it('loads both tarballs through plain Node and mounts their base image and overl const overlay = packer.packVfsOverlay([{ mount: 'workspace', directory: fileURLToPath(new URL('./overlay', import.meta.url)) }]) runtime.loadVfsOverlay(await runtime.inflateImage(overlay.image, 'packed overlay'), '/dsh', vfs) assert.equal(vfs.readFileSync('/dsh/workspace/hello.txt', 'utf8'), 'packed worker pair\\n') + mkdirSync('home/sessions/project/preview', { recursive: true }) + const historical = JSON.stringify({ type: 'session', version: 3, id: 'preview', createdAt: 1, isSeeded: false, delegationDepth: 0 }) + '\\n' + writeFileSync('home/sessions/project/preview/session.v3.jsonl', historical) + const prepared = packer.packPreviewFixture([{ mount: 'home', directory: fileURLToPath(new URL('./home', import.meta.url)) }]) + runtime.loadVfsOverlay(await runtime.inflateImage(prepared.image, 'prepared preview'), '/dsh', vfs) + assert.equal(vfs.readFileSync('/dsh/home/sessions/project/preview/session.v3.jsonl', 'utf8'), historical) + const current = JSON.parse(vfs.readFileSync('/dsh/home/sessions/project/preview/session.v' + sessionFormatCatalog.currentVersion + '.jsonl', 'utf8')) + assert.equal(current.version, sessionFormatCatalog.currentVersion) console.log('packed image and overlay mounted') ` await writeFile(join(root, 'consumer.mjs'), script) diff --git a/packages/experimental/webworker-packer/tests/preview.spec.ts b/packages/experimental/webworker-packer/tests/preview.spec.ts new file mode 100644 index 0000000000..2c5c381059 --- /dev/null +++ b/packages/experimental/webworker-packer/tests/preview.spec.ts @@ -0,0 +1,135 @@ +import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { afterEach, describe, expect, it } from 'vitest' +import { createSessionFormatCatalogWithChildren, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { sessionFormatLogFilename } from '@deepseek-ai/dsh-session-format' +import { packPreviewFixture } from '../src/preview.ts' +import { packVfsOverlay } from '../src/pack.ts' +import { previewFixtures } from '../src/repository.ts' + +const repoRoot = fileURLToPath(new URL('../../../../', import.meta.url)) +const roots: string[] = [] +const currentVersion = sessionFormatCatalog.currentVersion +const text = (bytes: Uint8Array | undefined): string => new TextDecoder().decode(bytes) + +afterEach(() => { + for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }) +}) + +function source() { + const root = mkdtempSync(join(tmpdir(), 'dsh-preview-source-')) + roots.push(root) + const session = join(root, 'sessions', 'project', 'example') + mkdirSync(session, { recursive: true }) + return { + trees: [{ mount: 'home', directory: root }], + put(version: number, body = '', overrides: Record = {}) { + const path = join(session, sessionFormatLogFilename(version)) + const header = { type: 'session', version, id: 'example', createdAt: 1, isSeeded: false, delegationDepth: 0, ...overrides } + writeFileSync(path, JSON.stringify(header) + '\n' + body) + return path + }, + } +} + +function restore(bytes: Uint8Array | undefined) { + const [header, ...rows] = text(bytes).trimEnd().split('\n').map(row => JSON.parse(row) as unknown) + const reader = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const row of rows) reader.decodeRow(row) + return reader.finish() +} + +describe('Node preparation of Preview Session data', () => { + it('packs strictly migrated current successors beside every unchanged example file', () => { + const fixture = previewFixtures(repoRoot)[0]! + const original = packVfsOverlay(fixture.trees) + const projected = packPreviewFixture(fixture.trees) + const currentFiles = Object.keys(projected.files).filter(path => path.endsWith('/' + sessionFormatLogFilename(currentVersion))) + expect(currentFiles).toHaveLength(3) + for (const [path, bytes] of Object.entries(original.files)) expect(projected.files[path], path).toEqual(bytes) + for (const path of currentFiles) { + const sourcePath = path.replace(/\/session\.v\d+\.jsonl$/u, '/session.v3.jsonl') + const historical = restore(original.files[sourcePath]) + const current = restore(projected.files[path]) + const appended = path.includes('/preview-showcase/') ? [ + { version: 0, childId: 'preview-architecture-review', childCreatedAt: 1787472100000, mode: 'one-shot', label: 'Review preview architecture' }, + { version: 0, childId: 'preview-follow-up-builder', childCreatedAt: 1787472200000, mode: 'continuable', label: 'Continue preview verification' }, + ].map((data, index) => ({ type: 'subagent/catalog', seq: historical.events.length + index, + time: historical.events.at(-1)!.time, data })) : [] + expect(current).toEqual({ ...historical, events: [...historical.events, ...appended] }) + expect(JSON.parse(text(projected.files[path]).split('\n')[0]!)).toMatchObject({ version: currentVersion }) + } + expect(packPreviewFixture(fixture.trees).image).toEqual(projected.image) + expect(packVfsOverlay(fixture.trees).files).toEqual(original.files) + }) + + it.each(['missing-descriptor', 'other-root', 'other-origin', 'current-child'] as const)('adds catalog facts only for supported direct subagent children in the same root: %s', (mode) => { + const fixture = source() + const parent = fixture.put(3) + const childDirectory = join(fixture.trees[0]!.directory, 'sessions', mode === 'other-root' ? 'other' : 'project', 'child') + mkdirSync(childDirectory, { recursive: true }) + const version = mode === 'current-child' ? currentVersion : 3 + const child = { type: 'session', version, id: 'child', createdAt: 2, isSeeded: false, + delegationDepth: 1, parentSession: 'example', ...(mode === 'other-origin' ? {} : { origin: 'subagent' }) } + const descriptor = { type: 'subagent/descriptor', seq: 0, time: 3, + data: { version: 3, mode: 'one-shot', provider: 'spawn' } } + const childPath = join(childDirectory, sessionFormatLogFilename(version)) + writeFileSync(childPath, + JSON.stringify(child) + '\n' + (mode === 'current-child' ? JSON.stringify(descriptor) + '\n' : '')) + const before = readFileSync(parent) + const childBefore = readFileSync(childPath) + const original = packVfsOverlay(fixture.trees) + const packed = packPreviewFixture(fixture.trees) + const restored = restore(packed.files[`home/sessions/project/example/${sessionFormatLogFilename(currentVersion)}`]) + expect(restored.inheritedEventCount).toBe(0) + expect(restored.events).toEqual(mode === 'current-child' ? [{ type: 'subagent/catalog', seq: 0, time: 1, + data: { version: 0, childId: 'child', childCreatedAt: 2, mode: 'one-shot' } }] : []) + for (const [path, bytes] of Object.entries(original.files)) expect(packed.files[path], path).toEqual(bytes) + expect(readFileSync(parent)).toEqual(before) + expect(readFileSync(childPath)).toEqual(childBefore) + }) + + it('uses the highest generation and leaves an already-current image byte-identical', () => { + const fixture = source() + const older = fixture.put(3, '{invalid historical data}\n') + fixture.put(currentVersion) + const original = packVfsOverlay(fixture.trees) + expect(packPreviewFixture(fixture.trees).image).toEqual(original.image) + expect(text(original.files['home/sessions/project/example/session.v3.jsonl'])).toBe(readFileSync(older, 'utf8')) + }) + + it('keeps an overlay without Sessions opaque', () => { + const fixture = source() + expect(packPreviewFixture(fixture.trees)).toEqual(packVfsOverlay(fixture.trees)) + }) + + it.each(['future', 'corrupt', 'unknown-required'] as const)('refuses selected %s data without falling back or changing inputs', (mode) => { + const fixture = source() + fixture.put(3) + const path = fixture.put(mode === 'future' ? currentVersion + 1 : currentVersion, + mode === 'corrupt' ? '{invalid JSON}\n' + : mode === 'unknown-required' ? JSON.stringify({ type: 'external/required', seq: 0, time: 1, data: null }) + '\n' : '') + const before = readFileSync(path) + expect(() => packPreviewFixture(fixture.trees)).toThrow() + expect(readFileSync(path)).toEqual(before) + }) + + it.each([{ version: 2 }, { id: 'other' }])('refuses selected metadata that disagrees with its location: %j', (overrides) => { + const fixture = source() + fixture.put(3, '', overrides) + expect(() => packPreviewFixture(fixture.trees)).toThrow('disagrees with its Session header') + }) + + it('refuses a torn physical tail and compressed Session generations', () => { + const fixture = source() + const path = fixture.put(3) + const bytes = readFileSync(path) + writeFileSync(path, bytes.subarray(0, -1)) + expect(() => packPreviewFixture(fixture.trees)).toThrow('torn physical tail') + writeFileSync(path, bytes) + writeFileSync(join(dirname(path), sessionFormatLogFilename(currentVersion) + '.zstd'), 'compressed data') + expect(() => packPreviewFixture(fixture.trees)).toThrow('canonical raw Session generation') + }) +}) diff --git a/packages/experimental/webworker-packer/tsconfig.json b/packages/experimental/webworker-packer/tsconfig.json index 152b9ad8c2..9d99bdf7b1 100644 --- a/packages/experimental/webworker-packer/tsconfig.json +++ b/packages/experimental/webworker-packer/tsconfig.json @@ -19,6 +19,15 @@ }, { "path": "../../util/home-paths" + }, + { + "path": "../../session/session-format" + }, + { + "path": "../../session/session-format-catalog" + }, + { + "path": "../../session/session-format-v3-to-v4" } ] } diff --git a/packages/experimental/webworker-runtime/README.i18n.yaml b/packages/experimental/webworker-runtime/README.i18n.yaml index 1e6f283ded..d6fa266c66 100644 --- a/packages/experimental/webworker-runtime/README.i18n.yaml +++ b/packages/experimental/webworker-runtime/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/experimental/webworker-runtime/README.md -README.md: 6a6911824c8c71b3deb5037d1ecf629771211a26 -README.zh.md: c0ef4275507725bc6f1178ab2568c4fb6127479a +README.md: ce98accac7abb2241f79b16e596e68e1d1fbdd95 +README.zh.md: cc3cf583bb77ed0d3e9611f8d8543f39b9ea9d18 diff --git a/packages/experimental/webworker-runtime/README.md b/packages/experimental/webworker-runtime/README.md index 6a6911824c..ce98accac7 100644 --- a/packages/experimental/webworker-runtime/README.md +++ b/packages/experimental/webworker-runtime/README.md @@ -28,11 +28,11 @@ The public npm package exposes the runtime library at its root, the self-contain Three build artifacts and one source-owned process layer: - **`lib/index.js` (assembly library)** — `createWorkerHost`/`startWorkerHost` mount the base image and any ordered data overlays (`storage/`), install the module loader (`module-system/`) and the `process` shim, boot the tree through the image's own `dsh-app-boot`, and hand the tunnel its serving seams. Overlays may replace files only under `home/` and `workspace/`; they cannot replace the base manifest, configuration, or modules. The image layout contract (`image-layout.ts`: virtual root, config/manifest paths, empty directories, the `lowered` wrapper-contract gate) is shared with the packer. Boot patches force the deployment-shaped rows: frontend serving off, JSONL session logs on the plaintext path, preset roots onto the image's `config/agent-presets`. -- **`lib/worker.js` (worker bundle)** — the assembly plus this package's Node-compatibility layer as one self-contained ES module. The module proxy table (`module-proxies.ts`) is the only platform fork: `node:*` builtins over VFS/tunnel/browser primitives, structural stubs that fail loud on the console for what a browser cannot do, and native/binary package replacements. `node:module` supplies `createRequire().resolve` and `.resolve.paths()` over the image package root, so unchanged packages can discover manifests without evaluating their modules. The global `process` shim carries Node detection fields including `title`, preventing Worker execution from entering DOM-only branches. The pack-time parser reports statically named module requests, including module-scope direct calls of the form `createRequire(import.meta.url)('pkg')` through a named `node:module` or `module` import, to the packer's reachability walk. Stored, CommonJS-obtained, and rebased `createRequire` calls require image entry seeds. VFS mutations drive `node:fs` callback, polling, and promise watchers; open descriptors retain file identity and access mode across rename, replacement, and unlink, `FileHandle.stat({ bigint: true })` reports the same device and inode identity as a path stat while the name still refers to that file, and `FileHandle.chmod()` updates the opened file identity; `readable-stream` supplies the stream state machine used by file streams and unchanged image packages such as Chokidar and readdirp. AsyncLocalStorage carries sync-stack causality across `await` through the snapshot/restore faces the pack-time lowering injects. The worker holds no compiler: an image the packer did not lower is refused at mount. The callback `fs.realpath.native` alias resolves within the mounted VFS and supports `util.promisify`. +- **`lib/worker.js` (worker bundle)** — the assembly plus this package's Node-compatibility layer as one self-contained ES module. The module proxy table (`module-proxies.ts`) is the only platform fork: `node:*` builtins over VFS/tunnel/browser primitives, structural stubs that fail loud on the console for what a browser cannot do, and native/binary package replacements. `node:module` supplies `createRequire().resolve` and `.resolve.paths()` over the image package root, so unchanged packages can discover manifests without evaluating their modules. The `node:util` JSON-data comparator compares own enumerable properties, preserving Node admission decisions for recorded fields such as `__proto__`. The global `process` shim carries Node detection fields including `title`, preventing Worker execution from entering DOM-only branches. The pack-time parser reports statically named module requests, including module-scope direct calls of the form `createRequire(import.meta.url)('pkg')` through a named `node:module` or `module` import, to the packer's reachability walk. Stored, CommonJS-obtained, and rebased `createRequire` calls require image entry seeds. VFS mutations drive `node:fs` callback, polling, and promise watchers; open descriptors retain file identity and access mode across rename, replacement, and unlink, `FileHandle.stat({ bigint: true })` reports the same device and inode identity as a path stat while the name still refers to that file, and `FileHandle.chmod()` updates the opened file identity; `readable-stream` supplies the stream state machine used by file streams and unchanged image packages such as Chokidar and readdirp. AsyncLocalStorage carries sync-stack causality across `await` through the snapshot/restore faces the pack-time lowering injects. The worker holds no compiler: an image the packer did not lower is refused at mount. The callback `fs.realpath.native` alias resolves within the mounted VFS and supports `util.promisify`. - **`src/shell/` (the worker's own process layer)** — a browser worker cannot fork, so `node:child_process` is not a stub but an implementation: `spawn` starts the command in its own Web Worker — this same bundle, told by its first frame to be a shell process — and reports it through the `ChildProcess` surface the subprocess service consumes. The command runs off the host's thread, `SIGKILL` terminates it whatever it is doing, and it reaches the VFS only by message (the host serves those frames). Worker platform executables preserve native-package protocols such as Landlock without replacing their JavaScript packages or coupling their implementations to `node:child_process`; ordinary commands use the package's evaluator and coreutils command table. The grammar is `@yarnpkg/parsers`' `parseShell`, while `execSync`/`fork` still refuse because they need a real process. - **`lib/client.js` (page half)** — startup has two independent stages. `chooseWorkerHostSource({ image?, fixtureManifest? })` optionally owns the boot barrier and fixture manifest: without `preview-fixture` it waits at the source chooser, while a valid query selects directly; either path returns ordered overlays. `connectWorkerHost(worker, { image?, overlays? })` remains the public base-runtime connector; callers that skip the chooser get an empty overlay list. `apps/web` invokes both and supplies its statically bundled Worker. The opening `init` frame carries the base and ordered overlay URLs, the boot payload delivers the structured index-injection table, and `applyIndexInjections` executes it before the shell entry runs. Script preload rows are advisory and skipped because `/plugins` resources resolve only through the tunnel; `loadBundle` fetches each combo on first demand, embeds its tunnel-only source map as a Base64 data URL, and executes the script as a Blob. The tunnel also exposes fetch-shaped transport, the independent file-upload carrier, and the API client. Request frames preserve Blob bodies through structured clone and transfer `ReadableStream` ownership. The Host Worker streams both forms into the route, so neither browser thread creates a complete byte array for a generic-file upload. -Acceptance lives in `apps/web/tests/preview-boot.e2e.ts`, which serves the real built pages and drives the pre-boot chooser plus Worker activation in headless Chromium. The empty selection exercises first-run startup. The `vfs-example` overlay supplies ordinary workspace files and plaintext persistence artifacts for cold Workspace/Session discovery, tool presentation, subagent navigation, and history paging without a model request. The fixture generator owns current-generation logs and the projection cache; committed predecessor logs remain byte-identical alongside them. The chooser reserves WebFS as a separate user-authorized source; that provider does not read the built-in fixture. +Acceptance lives in `apps/web/tests/preview-boot.e2e.ts`, which serves the real built pages and drives the pre-boot chooser plus Worker activation in headless Chromium. The empty selection exercises first-run startup. The `vfs-example` overlay supplies ordinary workspace files and plaintext persistence artifacts for cold Workspace/Session discovery, tool presentation, subagent navigation, and history paging without a model request. The [packer](../webworker-packer/README.md) prepares current-generation successors from committed historical logs in Node; those source logs remain byte-identical in the overlay. The fixture generator owns the acceptance test's current projection cache. The chooser reserves WebFS as a separate user-authorized source; that provider does not read the built-in fixture. The [built-bundle import sweep](tests/compile/transform-corpus-check.ts) checks bare Node imports after the library build. Its Dockkit exception accepts Node’s unknown-`.css`-extension refusal for any stylesheet rather than one pinned path; another extension, error code, or message, and an unexpectedly successful exempt import, remain errors. See the [stylesheet exemption decision](../../../.agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.md). diff --git a/packages/experimental/webworker-runtime/README.zh.md b/packages/experimental/webworker-runtime/README.zh.md index c0ef427550..cc3cf583bb 100644 --- a/packages/experimental/webworker-runtime/README.zh.md +++ b/packages/experimental/webworker-runtime/README.zh.md @@ -28,11 +28,11 @@ kind: "package-library" 一条 tsdown 管线产出三个构建产物;另有一层由源码维护的进程实现: - **`lib/index.js`(装配库)**——`createWorkerHost`/`startWorkerHost` 挂载基础镜像和按序排列的数据 overlays(`storage/`)、安装模块加载器(`module-system/`)与 `process` shim、经镜像自带的 `dsh-app-boot` 启动插件树,并把服务 seam 交给隧道。Overlay 只能替换 `home/` 与 `workspace/` 下的文件,不能替换基础 manifest、配置或模块。镜像布局契约(`image-layout.ts`:虚拟根、config/manifest 路径、空目录、`lowered` 包装契约门)与 packer 共享。boot patch 强制部署形态行:关前端静态服务、JSONL 会话日志走明文、preset 根指向镜像内 `config/agent-presets`。 -- **`lib/worker.js`(worker 束)**——装配库加本包的 Node 兼容层,合成一个自含 ES module。模块代理表(`module-proxies.ts`)是唯一平台叉口:`node:*` 内建走 VFS、隧道和浏览器原语,浏览器做不到的走结构化 stub(调用即在 console 报错并抛出),native/binary 包则替换执行后端。`node:module` 在镜像 package 根之上提供 `createRequire().resolve` 与 `.resolve.paths()`,使未修改的包无需执行目标模块即可发现 manifest。全局 `process` shim 带有包括 `title` 在内的 Node 环境识别字段,避免 Worker 执行误入仅适用于 DOM 的分支。pack 期解析器会把名称静态可知的模块请求报告给 packer 的可达性遍历,其中包括通过 `node:module` 或 `module` 具名导入在模块作用域直接发起的 `createRequire(import.meta.url)('pkg')` 调用。保存、经 CommonJS 获取或另设基准的 `createRequire` 调用需要镜像入口种子。VFS mutation 驱动 `node:fs` 的 callback、polling 和 promise watcher;打开的 descriptor 在 rename、replacement 和 unlink 后仍保留文件身份与访问模式,只要文件名仍指向该文件,`FileHandle.stat({ bigint: true })` 报告的 device 与 inode 身份就与路径 stat 相同,`FileHandle.chmod()` 则更新打开文件身份的权限;`readable-stream` 提供文件流以及 Chokidar、readdirp 等未修改镜像包所用的流状态机。AsyncLocalStorage 经 pack 时降低注入的 snapshot/restore 面在 `await` 间携带同步栈因果。worker 不带编译器:packer 未降低的镜像在挂载时被拒。回调式 `fs.realpath.native` 别名在已挂载的 VFS 内解析路径,并支持 `util.promisify`。 +- **`lib/worker.js`(worker 束)**——装配库加本包的 Node 兼容层,合成一个自含 ES module。模块代理表(`module-proxies.ts`)是唯一平台叉口:`node:*` 内建走 VFS、隧道和浏览器原语,浏览器做不到的走结构化 stub(调用即在 console 报错并抛出),native/binary 包则替换执行后端。`node:module` 在镜像 package 根之上提供 `createRequire().resolve` 与 `.resolve.paths()`,使未修改的包无需执行目标模块即可发现 manifest。`node:util` 的 JSON 数据比较器检查可枚举的自有属性,使 `__proto__` 等记录字段的准入判定与 Node 一致。全局 `process` shim 带有包括 `title` 在内的 Node 环境识别字段,避免 Worker 执行误入仅适用于 DOM 的分支。pack 期解析器会把名称静态可知的模块请求报告给 packer 的可达性遍历,其中包括通过 `node:module` 或 `module` 具名导入在模块作用域直接发起的 `createRequire(import.meta.url)('pkg')` 调用。保存、经 CommonJS 获取或另设基准的 `createRequire` 调用需要镜像入口种子。VFS mutation 驱动 `node:fs` 的 callback、polling 和 promise watcher;打开的 descriptor 在 rename、replacement 和 unlink 后仍保留文件身份与访问模式,只要文件名仍指向该文件,`FileHandle.stat({ bigint: true })` 报告的 device 与 inode 身份就与路径 stat 相同,`FileHandle.chmod()` 则更新打开文件身份的权限;`readable-stream` 提供文件流以及 Chokidar、readdirp 等未修改镜像包所用的流状态机。AsyncLocalStorage 经 pack 时降低注入的 snapshot/restore 面在 `await` 间携带同步栈因果。worker 不带编译器:packer 未降低的镜像在挂载时被拒。回调式 `fs.realpath.native` 别名在已挂载的 VFS 内解析路径,并支持 `util.promisify`。 - **`src/shell/`(worker 自己的进程层)**——浏览器 worker 无法 fork,所以 `node:child_process` 不是 stub 而是实现:`spawn` 把命令放进它自己的 Web Worker——就是这同一个束,由首帧告诉它「你是 shell 进程」——并以 subprocess 服务消费的 `ChildProcess` 面报告结果。命令不占宿主线程,`SIGKILL` 不管它在干什么都能终止它,而它只能靠消息触达 VFS(由宿主应答这些帧)。Worker 平台 executable 在不替换 JavaScript 包、也不把具体实现耦合进 `node:child_process` 的情况下保持 Landlock 等 native 包协议;普通命令使用本包的求值器与 coreutils 命令表。语法来自 `@yarnpkg/parsers` 的 `parseShell`,而 `execSync`/`fork` 依然拒绝,因为它们需要真进程。 - **`lib/client.js`(页面半)**——启动分为相互独立的两段。`chooseWorkerHostSource({ image?, fixtureManifest? })` 可选地拥有 boot barrier 与 fixture manifest:没有 `preview-fixture` 时停在来源选择面板,合法 query 则直接选择;两条路径都返回按序排列的 overlays。`connectWorkerHost(worker, { image?, overlays? })` 仍是公开的基础运行态连接器;调用方跳过选择器时 overlay 列表为空。`apps/web` 调用这两段并提供静态打包的 Worker。开局 `init` 帧携带基础镜像与按序排列的 overlay URL,boot 载荷送达结构化 index 注入表,`applyIndexInjections` 在壳入口运行前逐行执行。脚本 preload 行只是提示,因此会被跳过:`/plugins` 资源只能经 tunnel 解析,`loadBundle` 会在首次需要时获取 combo、把仅 tunnel 可达的 sourcemap 内嵌为 Base64 data URL,再以 Blob 执行脚本。Tunnel 还暴露 fetch 形式的传输、独立文件上传载体和 API 客户端。请求帧通过结构化克隆保留 Blob 请求体,并转移 `ReadableStream` 的所有权。Host Worker 将两种请求体都逐块送入路由,因此通用文件上传不会在任何浏览器线程创建完整字节数组。 -验收在 `apps/web/tests/preview-boot.e2e.ts`:静态服务真实构建页面,在 headless Chromium 里驱动 pre-boot 选择面板与 Worker 激活。空白选择验证首次启动;`vfs-example` overlay 提供普通 workspace 文件与明文 persistence 产物,无需模型请求即可验证 Workspace/Session 冷发现、工具呈现、subagent 导航和历史分页。fixture 生成器负责当前代日志与投影缓存;已提交的前代日志逐字节保持不变,与它们并存。选择面板为 WebFS 保留独立的用户授权来源;该 provider 不读取内置 fixture。 +验收在 `apps/web/tests/preview-boot.e2e.ts`:静态服务真实构建页面,在 headless Chromium 里驱动 pre-boot 选择面板与 Worker 激活。空白选择验证首次启动;`vfs-example` overlay 提供普通 workspace 文件与明文 persistence 产物,无需模型请求即可验证 Workspace/Session 冷发现、工具呈现、subagent 导航和历史分页。[打包器](../webworker-packer/README.zh.md)在 Node 中根据已提交的历史日志准备当前代后继文件;这些源日志在 overlay 中逐字节保持不变。fixture 生成器负责验收测试的当前投影缓存。选择面板为 WebFS 保留独立的用户授权来源;该 provider 不读取内置 fixture。 [已构建 bundle 导入检查](tests/compile/transform-corpus-check.ts)在库构建后检查裸 Node 导入。Dockkit 例外接受 Node 针对任意样式表报告的未知 `.css` 扩展名错误,而不限定某一固定路径;其他扩展名、错误码或消息,以及意外成功的豁免导入,仍然报错。参见 [样式表豁免决策](../../../.agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.zh.md)。 diff --git a/packages/experimental/webworker-runtime/src/node/builtin_modules/implemented/util.ts b/packages/experimental/webworker-runtime/src/node/builtin_modules/implemented/util.ts index b18d52f20e..7fc20b8b58 100644 --- a/packages/experimental/webworker-runtime/src/node/builtin_modules/implemented/util.ts +++ b/packages/experimental/webworker-runtime/src/node/builtin_modules/implemented/util.ts @@ -79,7 +79,7 @@ export function format(template: unknown, ...args: unknown[]): string { } /** - * Structural deep equality, as `isDeepStrictEqual` defines it for plain data. + * Structural deep equality over own enumerable properties, as `isDeepStrictEqual` defines it for plain data. * @param left - first value. * @param right - second value. * @returns true when both sides are structurally identical. @@ -95,7 +95,7 @@ export function isDeepStrictEqual(left: unknown, right: unknown): boolean { const leftKeys = Object.keys(left) const rightKeys = Object.keys(right) if (leftKeys.length !== rightKeys.length) return false - return leftKeys.every(key => key in right + return leftKeys.every(key => Object.hasOwn(right, key) && isDeepStrictEqual((left as Record)[key], (right as Record)[key])) /* jscpd:ignore-end */ } diff --git a/packages/experimental/webworker-runtime/tests/node/shim-diff.spec.ts b/packages/experimental/webworker-runtime/tests/node/shim-diff.spec.ts index c6f28163af..4be6aff419 100644 Binary files a/packages/experimental/webworker-runtime/tests/node/shim-diff.spec.ts and b/packages/experimental/webworker-runtime/tests/node/shim-diff.spec.ts differ diff --git a/packages/experimental/webworker-runtime/tests/vfs-example-fixture.spec.ts b/packages/experimental/webworker-runtime/tests/vfs-example-fixture.spec.ts index 9ea467ea14..b3d0c106eb 100644 --- a/packages/experimental/webworker-runtime/tests/vfs-example-fixture.spec.ts +++ b/packages/experimental/webworker-runtime/tests/vfs-example-fixture.spec.ts @@ -2,6 +2,7 @@ import { readFileSync, readdirSync } from 'node:fs' import { join, relative } from 'node:path' import { describe, expect, it } from 'vitest' import { SESSION_FORMAT_VERSION, Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' +import { createSessionFormatCatalogWithChildren } from '@deepseek-ai/dsh-session-format-catalog' import { generationLogFilename, scanLog, @@ -37,6 +38,14 @@ function readSession(id: string): ReturnType { return scanLog(Buffer.from(generated)) } +function restoreSession(content: string, version: number) { + const [header, ...events] = content.trimEnd().split('\n').map(line => JSON.parse(line) as unknown) + expect(header).toMatchObject({ type: 'session', version }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const event of events) restore.decodeRow(event) + return restore.finish() +} + function textOf(event: SessionEvent): string { if (event.type === 'user/message') { return event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('\n') @@ -48,17 +57,27 @@ function textOf(event: SessionEvent): string { } describe('WebWorker preview VFS example', () => { - it('matches its deterministic source byte for byte', () => { + it('retains V3 inputs that strictly restore to the deterministic current output', () => { const expected = buildVfsExampleFiles() + const currentName = generationLogFilename(SESSION_FORMAT_VERSION, 'none') + const committedPath = (path: string): string => path.endsWith(`/${currentName}`) + ? `${path.slice(0, -currentName.length)}session.v3.jsonl` + : path const predecessors = Object.values(VFS_EXAMPLE_SESSION_IDS) .map(id => `home/sessions/--dsh-workspace--/${id}/session.v2.jsonl`) - expect(filesUnder(VFS_EXAMPLE_ROOT)).toEqual([...expected.keys(), ...predecessors].sort()) + expect(filesUnder(VFS_EXAMPLE_ROOT)).toEqual([...expected.keys()].map(committedPath).concat(predecessors).sort()) for (const [path, content] of expected) { - expect(readFileSync(join(VFS_EXAMPLE_ROOT, path), 'utf8'), path).toBe(content) + if (path === 'home/storages/session_projcache.json') continue + const committed = readFileSync(join(VFS_EXAMPLE_ROOT, committedPath(path)), 'utf8') + if (path.endsWith(`/${currentName}`)) { + expect(restoreSession(committed, 3), path).toEqual(restoreSession(content, SESSION_FORMAT_VERSION)) + } else { + expect(committed, path).toBe(content) + } } }) - it('keeps the committed cache on the current generated projection', () => { + it('retains V3 cache identity while the generated cache uses the current writer', () => { const committed = JSON.parse(readFileSync( join(VFS_EXAMPLE_ROOT, 'home/storages/session_projcache.json'), 'utf8', @@ -80,9 +99,12 @@ describe('WebWorker preview VFS example', () => { const generatedText = buildVfsExampleFiles().get('home/storages/session_projcache.json') if (generatedText === undefined) throw new Error('missing generated VFS example projection cache') const generated = JSON.parse(generatedText) as typeof committed - expect(committed).toEqual(generated) - expect(committed.tables.sessions[VFS_EXAMPLE_SESSION_IDS.main]?.identity.formatVersion) - .toBe(SESSION_FORMAT_VERSION) + const expectedCurrent = structuredClone(committed) + for (const session of Object.values(expectedCurrent.tables.sessions)) { + expect(session.identity.formatVersion).toBe(3) + session.identity.formatVersion = SESSION_FORMAT_VERSION + } + expect(generated).toEqual(expectedCurrent) expect(generated.unit).toEqual({ name: projectionCacheDomainSpec.name, version: projectionCacheDomainSpec.version, @@ -135,7 +157,7 @@ describe('WebWorker preview VFS example', () => { 'read', 'write', 'bash', 'glob', 'grep', 'web_search', 'todo_write', 'subagent', 'subagent_fork', ])) expect(events.some(event => event.type === 'todo/write')).toBe(true) - expect(events.some(event => event.type === 'tool/result' && event.data.message.content[0].isError === true)).toBe(true) + expect(events.some(event => event.type === 'tool/result' && event.data.message.isError === true)).toBe(true) }) it('restores one-shot and continuable child Sessions with durable descriptors', () => { diff --git a/packages/experimental/webworker-runtime/tests/vfs-example-fixture.ts b/packages/experimental/webworker-runtime/tests/vfs-example-fixture.ts index 5422fc02cb..3ba332a5e6 100644 --- a/packages/experimental/webworker-runtime/tests/vfs-example-fixture.ts +++ b/packages/experimental/webworker-runtime/tests/vfs-example-fixture.ts @@ -336,14 +336,11 @@ function mainLog(): { step: 1, message: { id: `${call.id}-result`, - role: 'user', - content: [{ - type: 'tool-result', - toolCallId: call.id, - content: [{ type: 'text', text: call.result }], - isError: call.error !== undefined, - }], + role: 'tool', + toolCallId: call.id, source: { kind: 'tool', callId: call.id }, + content: [{ type: 'text', text: call.result }], + isError: call.error !== undefined, }, ...call.meta === undefined ? {} : { meta: call.meta }, ...call.error === undefined ? {} : { error: call.error }, diff --git a/packages/extensions/cordis-client-runner/src/client/api-catalog.ts b/packages/extensions/cordis-client-runner/src/client/api-catalog.ts index 7a54f8087e..0371943a75 100644 --- a/packages/extensions/cordis-client-runner/src/client/api-catalog.ts +++ b/packages/extensions/cordis-client-runner/src/client/api-catalog.ts @@ -201,14 +201,9 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ returns: 'a stable read-only source across same-id generations, with zero counts when none is live.', }, { - signature: 'setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void', - description: 'Mark whether a catalog menu is consuming live membership updates.', - parameters: [{ name: 'parentSessionId', description: 'catalog owner.' }, { name: 'open', description: 'current menu state.' }], - }, - { - signature: 'refreshSubagents(parentSessionId: SessionId): Promise', - description: 'Refresh one direct-child catalog.', - parameters: [{ name: 'parentSessionId', description: 'catalog owner.' }], + signature: 'refreshProjections(sessionId: SessionId): Promise', + description: 'Load all Session projections once per connection; retry an unsuccessful initial read.', + parameters: [{ name: 'sessionId', description: 'Session to inspect without opening its conversation.' }], returns: 'completion of the current or newly started refresh.', }, { @@ -219,8 +214,8 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ }, { signature: 'fork(opts: { sessionId: SessionId; atSeq?: number; increaseTitle?: boolean }): Promise', - description: 'Fork a session from a completed-turn prefix of the source; on resolution the child is in the catalog and may be explicitly retained.', - parameters: [{ name: 'opts', description: 'source session id, the optional event seq anchoring the cut (the boundary is the first turn/end at or after it; an in-log anchor in an open turn is unavailable rather than clipped backward), and whether to increment an inherited durable title before resolving.' }], + description: 'Fork a session from an exact inclusive prefix of the source; on resolution the child is catalogued and can be explicitly retained.', + parameters: [{ name: 'opts', description: 'source session id, the optional exact inclusive boundary seq (a real event seq the caller already knows; a cut inside an open turn is balanced Host-side with synthetic closers, and omission selects the latest completed-turn prefix), and whether to increment an inherited durable title before resolving.' }], returns: 'the child session id.', throws: ['when the fork fails, or when a requested child-title rename fails after creation.'], }, @@ -792,7 +787,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'QueueAction', - declaration: 'export type QueueAction = {\n readonly kind: \'edit\';\n readonly content: readonly ContentBlock[];\n} | {\n readonly kind: \'remove\';\n} | {\n readonly kind: \'steer\';\n};', + declaration: 'export type QueueAction = {\n readonly kind: \'edit\';\n readonly content: readonly TextBlock[];\n} | {\n readonly kind: \'remove\';\n} | {\n readonly kind: \'steer\';\n};', }, { name: 'RegisterFactory', diff --git a/packages/extensions/cordis-host-runner/src/index.ts b/packages/extensions/cordis-host-runner/src/index.ts index db56327a2d..3177924f88 100644 --- a/packages/extensions/cordis-host-runner/src/index.ts +++ b/packages/extensions/cordis-host-runner/src/index.ts @@ -9,6 +9,12 @@ import type { Fiber } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'cordis-host-runner': { kind: 'cordis-host-runner' } + } +} + import { TypertRemoteService, Remote } from '@deepseek-ai/dsh-typert-protocol' import type { JsonValue } from '@deepseek-ai/dsh-util-values' import { isPlugin, normalizeHandler } from './guard.ts' @@ -1042,7 +1048,7 @@ export class DynamicCordisRunnerService extends TypertRemoteService { } agent.steer(createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'cordis-host-runner' }, + source: { kind: 'cordis-host-runner' }, })) } @@ -1062,7 +1068,7 @@ export class DynamicCordisRunnerService extends TypertRemoteService { + `entryAbdicated: ${failure.abdicated}\n` + 'Report the Client render failure to the user; the definition can be stopped through the Cordis panel.', }], - source: { kind: 'plugin', plugin: 'cordis-host-runner' }, + source: { kind: 'cordis-host-runner' }, })) } @@ -1086,7 +1092,7 @@ export class DynamicCordisRunnerService extends TypertRemoteService { + 'The Plugin remains running. Report the Host handler failure to the user. If the handler needs a Service, either declare ' + 'that Service in the returned Plugin inject list or read it with ctx.get(name) and handle undefined.', }], - source: { kind: 'plugin', plugin: 'cordis-host-runner' }, + source: { kind: 'cordis-host-runner' }, })) } @@ -1109,7 +1115,7 @@ export class DynamicCordisRunnerService extends TypertRemoteService { + `(${run.pluginRunId}) after activation.\n${formatErrorDetails(failure)}\n` + 'The Plugin remains running. Report the guard rejection to the user; it can be stopped through the Cordis panel.', }], - source: { kind: 'plugin', plugin: 'cordis-host-runner' }, + source: { kind: 'cordis-host-runner' }, })) } /* jscpd:ignore-end */ @@ -1149,7 +1155,7 @@ export class DynamicCordisRunnerService extends TypertRemoteService { if (agents?.get(agent.id) !== agent) return agent.inject(createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'cordis-host-runner' }, + source: { kind: 'cordis-host-runner' }, })) } diff --git a/packages/extensions/tool-cordis/src/api-catalog.ts b/packages/extensions/tool-cordis/src/api-catalog.ts index 1c3f76aeb1..de5ef44f14 100644 --- a/packages/extensions/tool-cordis/src/api-catalog.ts +++ b/packages/extensions/tool-cordis/src/api-catalog.ts @@ -1752,8 +1752,8 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ }, { signature: '@Remote(\'fork\') fork(request: SessionForkRequest): Promise', - description: 'Fork one cold-readable completed-turn prefix into a new Session.', - parameters: [{ name: 'request', description: 'source Session and optional event anchor.' }], + description: 'Fork one cold-readable exact event prefix into a new Session. An omitted boundary selects the latest completed-turn prefix; an open cut receives synthetic fork closers.', + parameters: [{ name: 'request', description: 'source Session and optional exact inclusive event boundary.' }], returns: 'the new Session identity.', }, { @@ -1792,6 +1792,12 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ parameters: [{ name: 'request', description: 'durable address and last committed sequence already held by the caller.' }, { name: 'signal', description: 'cancellation owned by the Remote stream carrier.' }], returns: 'a complete opening snapshot followed by gap-free durable event frames and optional cursorless assistant-stream frames.', }, + { + signature: '@Remote(\'projections\') async projections(request: SessionProjectionsRequest, signal: AbortSignal): Promise', + description: 'Read all registered projections without activating an Agent.', + parameters: [{ name: 'request', description: 'Session whose current values are required.' }, { name: 'signal', description: 'cancellation for the Session observation.' }], + returns: 'complete baseline, or null when the Session does not exist.', + }, { signature: '@Remote({ mode: \'stream\' }) control(signal: AbortSignal): AsyncIterable', description: 'Stream a complete live-control baseline followed by replacement frames.', @@ -2162,7 +2168,7 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ }, { signature: 'fork(source: SessionForkSource, boundary?: SessionSeq, childSessionId?: SessionId): Session', - description: 'Create a live child session from a stable prefix of a live source. `boundary` is an inclusive source event seq; omitted means the source\'s current last event. The selected slice may end with a between-turn event but must not end inside an open turn.', + description: 'Create a live child session from an exact prefix of a live source. `boundary` is an inclusive source event seq; omitted means the source\'s current last event. An open tail receives synthetic tool results and step/turn closers with the forked cause. Closed steps and turns remain unchanged, including any failed tool calls already missing results. `inheritedEventCount` counts only copied source events, excluding these closers.', parameters: [{ name: 'source', description: 'Live source session object or id.' }, { name: 'boundary', description: 'Inclusive source event seq to fork through; omitted means the source\'s current last event, and omitted on an empty source forks an empty child.' }, { name: 'childSessionId', description: 'Optional child session id; omitted delegates to `SessionStore`\'s id policy.' }], returns: 'The created live child session.', }, @@ -2597,25 +2603,18 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ throws: ['{SubagentError} `UNAUTHORIZED` when a resident target belongs to a different parent or the supplied parent identity is stale.'], }, { - signature: 'listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise', - description: 'Enumerate the parent\'s direct session-backed subagents without loading or resuming an Agent. The Session query service supplies one live-preferred corpus and shared point observations; the projection cache supplies immutable descriptor hits without opening cold logs. The registered `subagent` projection remains the sole mode/label classifier.\n\nEvery query receives `signal`, and the listing rechecks cancellation around each await. Read rejections that settle after an abort become a stable `SubagentError` with code `CANCELLED`.', - parameters: [{ name: 'parentSessionId', description: 'parent session whose direct children are listed.' }, { name: 'signal', description: 'caller-owned cancellation forwarded to Session queries and observed around every read await.' }], - returns: 'children and per-child diagnostics ordered by `createdAt`, then id.', - throws: ['{@link SubagentError} when the projection registry or the session store is not mounted, or the caller cancels the listing.'], + signature: 'listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise', + description: 'Read the parent\'s durable direct-child catalog without loading or resuming an Agent. The service owns and releases the live-preferred Session observation.', + parameters: [{ name: 'parentSessionId', description: 'parent whose direct children are requested.' }, { name: 'signal', description: 'cancellation forwarded to the Session query.' }], + returns: 'catalog children in parent event order.', + throws: ['{@link SubagentError} when query or catalog projection is unavailable.', 'SessionQueryError when the parent cannot be read or the query is cancelled.'], }, { signature: 'listDescendants(rootSessionId: SessionId, signal?: AbortSignal): Promise', - description: 'Enumerate the root\'s complete session-backed subagent tree in stable pre-order from one live-preferred corpus, without loading or resuming an Agent. Ordinary sessions and one-shot children remain traversal nodes so continuable descendants below them are discovered; each returned entry adds its durable `parentId` and root-relative `depth`. Identity resolution, diagnostics, optional persistence, and cancellation follow the same projection-backed contract as listChildren.', + description: 'Enumerate the root\'s complete session-backed subagent tree in stable pre-order from one live-preferred corpus, without loading or resuming an Agent. Ordinary sessions and one-shot children remain traversal nodes so continuable descendants below them are discovered; each returned entry adds its durable `parentId` and root-relative `depth`. Identity resolution, diagnostics, optional persistence, and cancellation use the registered child identity projection and complete Session corpus.', parameters: [{ name: 'rootSessionId', description: 'session whose complete descendant tree is listed.' }, { name: 'signal', description: 'caller-owned cancellation forwarded to persistence reads and observed around every read await.' }], returns: 'children and per-candidate diagnostics with tree position, in stable pre-order.', - throws: ['{@link SubagentError} under the same conditions as {@link listChildren}.'], - }, - { - signature: '@Remote(\'list\') async remoteExportList(parentSessionId: SessionId, signal: AbortSignal): Promise', - description: 'Remote face of listChildren for one browser: the durable listing plus live Agent activity and the delivery-time parent availability hint. Parent availability is a hint; prompt performs the authoritative check. Named apart from the provider-name list, which owns the member.', - parameters: [{ name: 'parentSessionId', description: 'parent session whose direct children are listed.' }, { name: 'signal', description: 'carrier cancellation forwarded to Session queries.' }], - returns: 'the catalog view for that parent.', - throws: ['{RemoteError} `gateway/bad-request` for an empty parent id, `gateway/cancelled` for an aborted read, `subagent/projections-unavailable` when the deployment has no projection registry, otherwise `gateway/internal`.'], + throws: ['{@link SubagentError} when listing dependencies are unavailable or the caller cancels.'], }, { signature: '@Remote(\'prompt\') async prompt(request: SubagentPromptRequest, signal: AbortSignal): Promise', @@ -3552,9 +3551,9 @@ export const EVENT_API: readonly EventApiEntry[] = [ name: 'api-session/added', mode: 'emit', signature: '\'api-session/added\'(summary: SessionSummary): void', - summary: 'A Session became visible to Session list consumers.', - description: 'A Session became visible to Session list consumers.', - parameters: [{ name: 'summary', description: 'initial list row for the Session.' }], + summary: 'A Session became visible or its Agent was created or disposed.', + description: 'A Session became visible or its Agent was created or disposed. Consumers upsert the summary and replace its current running and availability state.', + parameters: [{ name: 'summary', description: 'current list row for the Session.' }], }, { name: 'api-session/error', @@ -3770,7 +3769,7 @@ export const EVENT_API: readonly EventApiEntry[] = [ signature: '\'llm/stream\'(this: LlmRuntime, options: GenerateOptions, next: () => AsyncIterable): AsyncIterable', summary: 'Waterfall around every streaming model call (retry, replay, routing).', description: 'Waterfall around every streaming model call (retry, replay, routing). Bound to the LlmRuntime; call `next()` to reach the resolved adapter\'s stream, or yield your own chunks to short-circuit.', - parameters: [{ name: 'options', description: 'the full request. A LOOP-built request carries the process-local {@link markAgentLoopRequest} identity and arrives deep-frozen (mutation throws): its content is a pure function of the session log (the reconstructability Agent Note), so listeners read it, never rewrite it. Hand-built calls do not carry that marker; their messages already obey the immutable creation contract.' }], + parameters: [{ name: 'options', description: 'the full request. A LOOP-built request carries the process-local {@link markAgentLoopRequest} identity and arrives deep-frozen (mutation throws): its content is a pure function of the session log (the reconstructability Agent Note), so listeners read it, never rewrite it. Hand-built calls do not carry that marker; callers own their request inputs and must keep them unchanged until the stream settles.' }], }, { name: 'permission-presets/catalog-changed', @@ -4174,7 +4173,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'AssistantMessage', - declaration: 'export interface AssistantMessage extends Message {\n readonly role: \'assistant\';\n readonly source: ModelMessageSource;\n}', + declaration: 'export interface AssistantMessage extends MessageBase {\n readonly role: \'assistant\';\n readonly source: ModelMessageSource;\n}', }, { name: 'AssistantProviderMetadata', @@ -4422,20 +4421,12 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'ContentBlockMap', - declaration: 'export interface ContentBlockMap {\n \'text\': TextBlock;\n \'reasoning\': ReasoningBlock;\n \'image\': ImageBlock;\n \'file\': FileBlock;\n \'tool-call\': ToolCallBlock;\n \'tool-result\': ToolResultBlock;\n}', + declaration: 'export interface ContentBlockMap {\n \'text\': TextBlock;\n \'reasoning\': ReasoningBlock;\n \'image\': ImageBlock;\n \'file\': FileBlock;\n \'tool-call\': ToolCallBlock;\n \'tool-addition\': ToolAdditionBlock;\n \'tool-removal\': ToolRemovalBlock;\n}', }, { name: 'ContentBlockType', declaration: 'export type ContentBlockType = keyof ContentBlockMap;', }, - { - name: 'ContextFormed', - declaration: 'export type ContextFormed = {\n readonly form?: never;\n} | {\n readonly form: \'instructions\';\n} | {\n readonly form: \'catalog\';\n} | {\n readonly form: \'snapshot\';\n readonly sections: readonly ContextSnapshotSection[];\n} | {\n readonly form: \'notice\';\n readonly summary: string;\n} | {\n readonly form: \'relay\';\n} | {\n readonly form: \'recall\';\n};', - }, - { - name: 'ContextSnapshotSection', - declaration: 'export interface ContextSnapshotSection {\n readonly name: string;\n readonly text: string;\n}', - }, { name: 'ContinuableCreateRequest', declaration: 'export interface ContinuableCreateRequest {\n readonly sessionId: SessionId;\n readonly parent: Agent;\n readonly signal: AbortSignal;\n}', @@ -4584,6 +4575,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'DeepSeekLlmApiJson', declaration: 'export type DeepSeekLlmApiJson = null | boolean | number | string | DeepSeekLlmApiJson[] | {\n [key: string]: DeepSeekLlmApiJson;\n};', }, + { + name: 'DeveloperMessage', + declaration: 'export interface DeveloperMessage extends MessageBase {\n readonly role: \'developer\';\n}', + }, { name: 'DiffCallView', declaration: 'export interface DiffCallView {\n card: \'diff\';\n title: string;\n diffs: FileDiff[];\n locations?: FileLocation[];\n}', @@ -4706,7 +4701,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'EpochHeader', - declaration: 'export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n}', + declaration: 'export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n system?: never;\n}', }, { name: 'FeedbackCategory', @@ -4798,7 +4793,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'GenerateOptions', - declaration: 'export interface GenerateOptions {\n provider: string;\n model: string;\n reasoningEffort?: ReasoningEffortId;\n messages: Message[];\n system?: string;\n tools?: ToolSchema[];\n temperature?: number;\n maxTokens?: number;\n stop?: string[];\n signal?: AbortSignal;\n sessionId?: Branded<\'SessionId\'>;\n purpose?: \'compaction\' | \'session-title\';\n}', + declaration: 'export interface GenerateOptions {\n provider: string;\n model: string;\n reasoningEffort?: ReasoningEffortId;\n messages: RequestMessage[];\n system?: string;\n tools?: ToolSchema[];\n temperature?: number;\n maxTokens?: number;\n stop?: string[];\n signal?: AbortSignal;\n sessionId?: Branded<\'SessionId\'>;\n purpose?: \'compaction\' | \'session-title\';\n}', }, { name: 'GenericCallView', @@ -5146,7 +5141,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'Message', - declaration: 'export interface Message {\n readonly id: MessageId;\n readonly role: \'system\' | \'user\' | \'assistant\';\n readonly content: ContentBlock[];\n readonly source: MessageSource;\n}', + declaration: 'export type Message = MessageRoleMap[keyof MessageRoleMap];', }, { name: 'MessageFeedbackDeleteRequest', @@ -5229,12 +5224,12 @@ export const TYPE_API: readonly TypeApiEntry[] = [ declaration: 'export type MessageId = Branded<\'MessageId\'>;', }, { - name: 'MessageSource', - declaration: 'export type MessageSource = MessageSourceMap[keyof MessageSourceMap];', + name: 'MessageRoleMap', + declaration: 'export interface MessageRoleMap {\n system: SystemMessage;\n developer: DeveloperMessage;\n user: UserMessage;\n assistant: AssistantMessage;\n tool: ToolResultMessage;\n}', }, { name: 'MessageSourceMap', - declaration: 'export interface MessageSourceMap {\n user: {\n kind: \'user\';\n };\n plugin: {\n kind: \'plugin\';\n plugin: string;\n } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n}', + declaration: 'export interface MessageSourceMap {\n user: {\n kind: \'user\';\n };\n model: ModelMessageSource;\n tool: ToolMessageSource;\n \'system-prompt\': SystemPromptMessageSource;\n}', }, { name: 'ModelCatalog', @@ -5522,7 +5517,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'QueueAction', - declaration: 'export type QueueAction = {\n readonly kind: \'edit\';\n readonly content: readonly ContentBlock[];\n} | {\n readonly kind: \'remove\';\n} | {\n readonly kind: \'steer\';\n};', + declaration: 'export type QueueAction = {\n readonly kind: \'edit\';\n readonly content: readonly TextBlock[];\n} | {\n readonly kind: \'remove\';\n} | {\n readonly kind: \'steer\';\n};', }, { name: 'ReadFileLine', @@ -5596,10 +5591,18 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'RequestImageAttachment', declaration: 'export interface RequestImageAttachment {\n variantId: ImageVariantId;\n attachment: ImageAttachmentRef;\n data: Uint8Array;\n mediaType: ImageMediaType;\n bytes: number;\n width: number;\n height: number;\n depth: \'uchar\';\n space: \'srgb\';\n hasAlpha: boolean;\n}', }, + { + name: 'RequestMessage', + declaration: 'export type RequestMessage = Message | RequestUserInput;', + }, { name: 'RequestRunOutcome', declaration: 'export type RequestRunOutcome = \'approved\' | \'completed\' | \'rejected\' | \'cancelled\' | \'failed\';', }, + { + name: 'RequestUserInput', + declaration: 'export interface RequestUserInput {\n readonly role: \'user\';\n readonly content: UserMessage[\'content\'];\n readonly id?: never;\n readonly source?: never;\n}', + }, { name: 'ResolvedAlwaysRetryPolicy', declaration: 'export interface ResolvedAlwaysRetryPolicy extends ResolvedRetryBackoff {\n readonly mode: \'always\';\n}', @@ -5726,7 +5729,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'Session', - declaration: 'export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n static create(id: SessionId, seed?: readonly SessionEvent[], header?: SessionHeader, inheritedEventCount?: SessionLogOffset, projections?: readonly SessionMessageProjection[]): Session;\n static fromRestore(id: SessionId, seed: readonly SessionEvent[], header: SessionHeader, inheritedEventCount: SessionLogOffset, eventState: SessionSeedEventState, projections?: readonly SessionMessageProjection[]): Session;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [\n opts: SurfaceIntent\n ] : [\n ]): SessionEvent;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}', + declaration: 'export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n readonly firstLifecycleSeq: SessionLogOffset;\n static create(id: SessionId, seed?: readonly SessionEvent[], header?: SessionHeader, inheritedEventCount?: SessionLogOffset, projections?: readonly SessionMessageProjection[]): Session;\n static fromRestore(id: SessionId, seed: readonly SessionEvent[], header: SessionHeader, inheritedEventCount: SessionLogOffset, eventState: SessionSeedEventState, projections?: readonly SessionMessageProjection[]): Session;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [\n opts: SurfaceIntent\n ] : [\n ]): SessionEvent;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}', }, { name: 'SessionAccess', @@ -5794,7 +5797,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SessionEventMap', - declaration: 'export interface SessionEventMap {\n \'turn/start\': {\n turn: number;\n };\n \'turn/end\': {\n turn: number;\n reason: TurnEndReason;\n };\n \'step/start\': {\n turn: number;\n step: number;\n };\n \'step/end\': {\n turn: number;\n step: number;\n };\n \'user/message\': UserMessage;\n \'system/message\': {\n turn: number;\n step: number;\n message: SystemMessage;\n };\n \'assistant/message\': {\n turn: number;\n step: number;\n message: AssistantMessage;\n stream: AssistantStreamRecord[];\n usage?: TokenUsage;\n interrupted?: true;\n };\n \'assistant/attempt\': {\n turn: number;\n step: number;\n stream: AssistantStreamRecord[];\n };\n \'tool/call\': {\n turn: number;\n step: number;\n callId: ToolCallId;\n name: string;\n arguments: string;\n };\n \'tool/result\': {\n turn: number;\n step: number;\n message: ToolResultMessage;\n error?: {\n name: string;\n code: string;\n reason?: string;\n };\n meta?: JsonValue;\n };\n \'request/header\': {\n header: EpochHeader;\n reason: RequestHeaderReason;\n startsSeries?: true;\n };\n \'request/context\': RequestContext;\n \'session/end-seed\': {\n inherited?: true;\n };\n}', + declaration: 'export interface SessionEventMap {\n \'turn/start\': {\n turn: number;\n };\n \'turn/end\': {\n turn: number;\n reason: TurnEndReason;\n };\n \'step/start\': {\n turn: number;\n step: number;\n };\n \'step/end\': {\n turn: number;\n step: number;\n };\n \'user/message\': UserMessage;\n \'developer/message\': {\n turn: number;\n step: number;\n message: DeveloperMessage;\n headerSeq?: SessionSeq;\n };\n \'system/message\': {\n turn: number;\n step: number;\n message: SystemMessage;\n };\n \'assistant/message\': {\n turn: number;\n step: number;\n message: AssistantMessage;\n stream: AssistantStreamRecord[];\n usage?: TokenUsage;\n interrupted?: true;\n };\n \'assistant/attempt\': {\n turn: number;\n step: number;\n stream: AssistantStreamRecord[];\n };\n \'tool/call\': {\n turn: number;\n step: number;\n callId: ToolCallId;\n name: string;\n arguments: string;\n };\n \'tool/result\': {\n turn: number;\n step: number;\n message: ToolResultMessage;\n error?: {\n name: string;\n code: string;\n reason?: string;\n };\n meta?: JsonValue;\n };\n \'request/header\': {\n header: EpochHeader;\n reason: RequestHeaderReason;\n startsSeries?: true;\n };\n \'request/context\': RequestContext;\n \'session/end-seed\': {\n /* …truncated — full shape in source */', }, { name: 'SessionEventMetadataFilter', @@ -6020,10 +6023,18 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'SessionProjectionMap', declaration: 'export interface SessionProjectionMap {\n}', }, + { + name: 'SessionProjectionsRequest', + declaration: 'export interface SessionProjectionsRequest {\n readonly sessionId: SessionId;\n}', + }, { name: 'SessionProjectionStateMap', declaration: 'export interface SessionProjectionStateMap {\n}', }, + { + name: 'SessionProjectionsValue', + declaration: 'export type SessionProjectionsValue = SessionProjectionBaseline | null;', + }, { name: 'SessionProjectionUpdate', declaration: 'export interface SessionProjectionUpdate {\n readonly sessionId: SessionId;\n readonly key: string;\n readonly value: JsonValue;\n readonly seq: number;\n}', @@ -6134,7 +6145,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SessionSummary', - declaration: 'export interface SessionSummary {\n readonly sessionId: SessionId;\n readonly updatedAt: number;\n readonly running: boolean;\n readonly blank: boolean;\n readonly parentSessionId?: SessionId;\n readonly origin?: \'subagent\';\n readonly cwd?: string;\n readonly projections?: SessionProjectionHints;\n}', + declaration: 'export interface SessionSummary {\n readonly agentAvailable: boolean;\n readonly sessionId: SessionId;\n readonly updatedAt: number;\n readonly running: boolean;\n readonly blank: boolean;\n readonly parentSessionId?: SessionId;\n readonly origin?: \'subagent\';\n readonly cwd?: string;\n readonly projections?: SessionProjectionHints;\n}', }, { name: 'SessionSurface', @@ -6409,8 +6420,12 @@ export const TYPE_API: readonly TypeApiEntry[] = [ declaration: 'export interface SubagentCapabilities {\n readonly agentOptions: boolean;\n readonly outputSchema: boolean;\n readonly depthLimit: boolean;\n readonly toolFilter: boolean;\n readonly persona: boolean;\n}', }, { - name: 'SubagentCatalog', - declaration: 'export interface SubagentCatalog {\n readonly entries: readonly SubagentListEntry[];\n readonly parentAvailable: boolean;\n}', + name: 'SubagentCatalogEntry', + declaration: 'export type SubagentCatalogEntry = {\n readonly id: SessionId;\n readonly createdAt: number;\n} & ({\n readonly mode: \'one-shot\';\n readonly label?: string;\n} | {\n readonly mode: \'continuable\';\n readonly label: string;\n});', + }, + { + name: 'SubagentCatalogRow', + declaration: 'export type SubagentCatalogRow = {\n readonly id: SessionId;\n readonly activity: \'running\' | \'inactive\';\n} & ({\n readonly mode: \'one-shot\';\n readonly label?: string;\n} | {\n readonly mode: \'continuable\';\n readonly label: string;\n});', }, { name: 'SubagentDescendantListEntry', @@ -6430,7 +6445,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SubagentListEntry', - declaration: 'export type SubagentListEntry = {\n readonly kind: \'child\';\n readonly id: SessionId;\n readonly activity: \'running\' | \'inactive\';\n readonly hasChildren: boolean;\n} & ({\n readonly mode: \'one-shot\';\n readonly label?: string;\n} | {\n readonly mode: \'continuable\';\n readonly label: string;\n}) | {\n readonly kind: \'diagnostic\';\n readonly id: SessionId;\n readonly reason: \'corrupt\' | \'unsupported\' | \'unavailable\';\n};', + declaration: 'export type SubagentListEntry = SubagentCatalogRow & {\n readonly kind: \'child\';\n readonly hasChildren: boolean;\n} | {\n readonly kind: \'diagnostic\';\n readonly id: SessionId;\n readonly reason: \'corrupt\' | \'unsupported\' | \'unavailable\';\n};', }, { name: 'SubagentPromptReceipt', @@ -6450,7 +6465,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SubagentResult', - declaration: 'export interface SubagentResult {\n readonly output: ContentBlock[];\n readonly structured?: unknown;\n readonly diagnostic?: string;\n readonly stopReason: SubagentStopReason;\n}', + declaration: 'export interface SubagentResult {\n readonly output: readonly ContentBlock[];\n readonly structured?: unknown;\n readonly diagnostic?: string;\n readonly stopReason: SubagentStopReason;\n}', }, { name: 'SubagentRun', @@ -6458,7 +6473,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SubagentRunEndInfo', - declaration: 'export interface SubagentRunEndInfo {\n readonly runId: SubagentRunId;\n readonly provider: string;\n readonly id: SessionId;\n readonly local: boolean;\n readonly stopReason: SubagentResult[\'stopReason\'];\n readonly lastAssistantMessage?: ContentBlock[];\n}', + declaration: 'export interface SubagentRunEndInfo {\n readonly runId: SubagentRunId;\n readonly provider: string;\n readonly id: SessionId;\n readonly local: boolean;\n readonly stopReason: SubagentResult[\'stopReason\'];\n readonly lastAssistantMessage?: readonly ContentBlock[];\n}', }, { name: 'SubagentRunId', @@ -6470,7 +6485,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SubagentRuntime', - declaration: 'export class SubagentRuntime extends TypertRemoteService {\n static Config: z;\n constructor(ctx: Context, config: Config);\n resolveMaxDepth(configured?: number | \'provider-managed\'): number | undefined;\n async startContinuable(spec: ContinuableStartSpec): Promise;\n async sendMessage(sender: Agent, targetId: SessionId, content: ContentBlock[], options: SubagentSendMessageOptions): Promise;\n interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void;\n async drainContinuableDescendants(parents: readonly Agent[]): Promise;\n async drainContinuableChildren(parent: Agent, childIds: readonly SessionId[]): Promise;\n listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise;\n listDescendants(rootSessionId: SessionId, signal?: AbortSignal): Promise;\n @Remote(\'list\')\n async remoteExportList(parentSessionId: SessionId, signal: AbortSignal): Promise;\n @Remote(\'prompt\')\n async prompt(request: SubagentPromptRequest, signal: AbortSignal): Promise;\n @Remote(\'interruptByParent\')\n interruptByParent(childSessionId: SessionId, parentSessionId: SessionId, mode: \'continuable\'): SubagentInterruptReceipt;\n registerProvider(provider: SubagentProvider): () => void;\n getProvider(name: string): SubagentProvider | undefined;\n list(): string[];\n async start(name: string, re /* …truncated — full shape in source */', + declaration: 'export class SubagentRuntime extends TypertRemoteService {\n static Config: z;\n constructor(ctx: Context, config: Config);\n resolveMaxDepth(configured?: number | \'provider-managed\'): number | undefined;\n async startContinuable(spec: ContinuableStartSpec): Promise;\n async sendMessage(sender: Agent, targetId: SessionId, content: ContentBlock[], options: SubagentSendMessageOptions): Promise;\n interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void;\n async drainContinuableDescendants(parents: readonly Agent[]): Promise;\n async drainContinuableChildren(parent: Agent, childIds: readonly SessionId[]): Promise;\n listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise;\n listDescendants(rootSessionId: SessionId, signal?: AbortSignal): Promise;\n @Remote(\'prompt\')\n async prompt(request: SubagentPromptRequest, signal: AbortSignal): Promise;\n @Remote(\'interruptByParent\')\n interruptByParent(childSessionId: SessionId, parentSessionId: SessionId, mode: \'continuable\'): SubagentInterruptReceipt;\n registerProvider(provider: SubagentProvider): () => void;\n getProvider(name: string): SubagentProvider | undefined;\n list(): string[];\n async start(name: string, request: SubagentStartRequest): Promise;\n}', }, { name: 'SubagentSendMessageOptions', @@ -6558,7 +6573,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SurfaceEventType', - declaration: 'export type SurfaceEventType = \'system/message\' | \'user/message\' | \'assistant/message\' | \'tool/result\';', + declaration: 'export type SurfaceEventType = \'system/message\' | \'developer/message\' | \'user/message\' | \'assistant/message\' | \'tool/result\';', }, { name: 'SurfaceIntent', @@ -6570,12 +6585,16 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'SystemMessage', - declaration: 'export interface SystemMessage extends Message {\n readonly role: \'system\';\n readonly source: MessageSourceMap[\'plugin\'];\n}', + declaration: 'export interface SystemMessage extends MessageBase {\n readonly role: \'system\';\n readonly source: MessageSourceMap[\'system-prompt\'];\n}', }, { name: 'SystemPrompt', declaration: 'export class SystemPrompt extends Service {\n static Config: z;\n constructor(ctx: Context, config: Config);\n section(section: PromptSection): () => void;\n getSectionOrder(name: PromptSectionOrderName): number;\n getContextOrder(name: PromptContextOrderName): number;\n context(context: PromptContext): () => void;\n suppressRuntimeContext(): () => void;\n tools(provider: (context: AssembleContext) => ToolProviderResult): () => void;\n variable(name: string, provider: (context: AssembleContext) => string | undefined): () => void;\n async assemble(context: AssembleContext = {}): Promise;\n}', }, + { + name: 'SystemPromptMessageSource', + declaration: 'export interface SystemPromptMessageSource {\n kind: \'system-prompt\';\n}', + }, { name: 'SystemPromptUpdate', declaration: 'export type SystemPromptUpdate = \'in-history\';', @@ -6752,6 +6771,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'TokenUsage', declaration: 'export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}', }, + { + name: 'ToolAdditionBlock', + declaration: 'export interface ToolAdditionBlock {\n type: \'tool-addition\';\n toolName: string;\n tool?: never;\n}', + }, { name: 'ToolCallKind', declaration: 'export type ToolCallKind = \'read\' | \'edit\' | \'delete\' | \'move\' | \'search\' | \'execute\' | \'fetch\' | \'other\';', @@ -6824,6 +6847,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'ToolProviderResult', declaration: 'export interface ToolProviderResult {\n readonly schemas: readonly ToolSchema[];\n readonly knownNames?: readonly string[];\n}', }, + { + name: 'ToolRemovalBlock', + declaration: 'export interface ToolRemovalBlock {\n type: \'tool-removal\';\n toolName: string;\n}', + }, { name: 'ToolRestriction', declaration: 'export interface ToolRestriction {\n readonly allow?: readonly string[];\n readonly deny?: readonly string[];\n}', @@ -6832,13 +6859,9 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'ToolResult', declaration: 'export interface ToolResult {\n content: ContentBlock[];\n isError: boolean;\n meta?: JsonValue;\n}', }, - { - name: 'ToolResultBlock', - declaration: 'export interface ToolResultBlock {\n type: \'tool-result\';\n toolCallId: ToolCallId;\n content: ContentBlock[];\n isError?: boolean;\n}', - }, { name: 'ToolResultMessage', - declaration: 'export interface ToolResultMessage extends Message {\n readonly role: \'user\';\n readonly content: [\n ToolResultBlock\n ];\n readonly source: ToolMessageSource;\n}', + declaration: 'export interface ToolResultMessage extends MessageBase {\n readonly role: \'tool\';\n readonly source: ToolMessageSource;\n readonly toolCallId: ToolCallId;\n readonly isError?: boolean;\n}', }, { name: 'ToolResultView', @@ -6858,7 +6881,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'ToolSchema', - declaration: 'export interface ToolSchema {\n name: string;\n description: string;\n parameters: Record;\n}', + declaration: 'export interface ToolSchema {\n deferLoading?: true;\n name: string;\n description: string;\n parameters: Record;\n}', }, { name: 'TurnEndCancelCause', @@ -6870,7 +6893,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'TurnEndReasonMap', - declaration: 'export interface TurnEndReasonMap {\n completed: {\n kind: \'completed\';\n };\n aborted: {\n kind: \'aborted\';\n reason: TurnEndCancelCause;\n };\n blocked: {\n kind: \'blocked\';\n };\n error: {\n kind: \'error\';\n error: LlmFailure;\n };\n \'max-tokens\': {\n kind: \'max-tokens\';\n };\n interrupted: {\n kind: \'interrupted\';\n };\n}', + declaration: 'export interface TurnEndReasonMap {\n completed: {\n kind: \'completed\';\n };\n aborted: {\n kind: \'aborted\';\n reason: TurnEndCancelCause;\n };\n blocked: {\n kind: \'blocked\';\n };\n error: {\n kind: \'error\';\n error: LlmFailure;\n };\n \'max-tokens\': {\n kind: \'max-tokens\';\n };\n interrupted: {\n kind: \'interrupted\';\n };\n forked: {\n kind: \'forked\';\n };\n}', }, { name: 'TypertCodec', @@ -6982,7 +7005,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'UserMessage', - declaration: 'export interface UserMessage extends Message {\n readonly role: \'user\';\n}', + declaration: 'export interface UserMessage extends MessageBase {\n readonly role: \'user\';\n}', }, { name: 'VerifiedWebhookDelivery', diff --git a/packages/fs/tool-fs-search/tests/tools.spec.ts b/packages/fs/tool-fs-search/tests/tools.spec.ts index 22511aef39..fd64cf16d3 100644 --- a/packages/fs/tool-fs-search/tests/tools.spec.ts +++ b/packages/fs/tool-fs-search/tests/tools.spec.ts @@ -15,6 +15,7 @@ import { Context } from '@deepseek-ai/cordis' import { createScope, type Scope } from '@deepseek-ai/dsh-scope' import { join, sep } from 'node:path' import { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SystemPrompt, { renderPrompt } from '@deepseek-ai/dsh-system-prompt' import ToolRuntime, { TOOL_ABORTED_BEFORE_DISPATCH, type ToolExecution, type ToolExecutionToken } from '@deepseek-ai/dsh-tools' import { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess' @@ -40,6 +41,12 @@ import { toWorkdirRelative, } from '@deepseek-ai/dsh-tool-fs-search' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal /** @@ -765,7 +772,7 @@ describe('glob results', () => { ctx.on('tools/post-execute', async () => ({ kind: 'accept', additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'glob context' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'glob context' }], source: { kind: 'test' }, })], })) subprocess.handler = () => runResult('a.ts\nb.ts\nc.ts\nd.ts\n') @@ -977,7 +984,7 @@ describe('grep results', () => { ctx.on('tools/post-execute', async () => ({ kind: 'accept', additionalContexts: [createUserMessage({ - content: [{ type: 'text', text: 'grep context' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'grep context' }], source: { kind: 'test' }, })], })) subprocess.handler = () => runResult([ diff --git a/packages/goal/goal-round-driver/src/index.ts b/packages/goal/goal-round-driver/src/index.ts index cac74fe66c..b8cffbfc29 100644 --- a/packages/goal/goal-round-driver/src/index.ts +++ b/packages/goal/goal-round-driver/src/index.ts @@ -58,7 +58,7 @@ function sameRound(source: GoalMessageSource, round: RoundIdentity): boolean { } /** Compare the complete queued record to the driver's reservation. */ -function sameQueued(content: ContentBlock[], source: MessageSource, attempt: RoundAttempt): boolean { +function sameQueued(content: readonly ContentBlock[], source: MessageSource, attempt: RoundAttempt): boolean { return isGoalRoundSource(source) && sameRound(source, attempt) && isDeepStrictEqual(content, attempt.content) } @@ -344,7 +344,7 @@ export function apply(ctx: Context): void { /** Fail closed unless the queued prompt still owns the exact live revision. */ function validReservation( state: DriverState, - content: ContentBlock[], + content: readonly ContentBlock[], source: GoalMessageSource, ): boolean { const attempt = state.attempt diff --git a/packages/goal/goal-round-driver/tests/goal-round-driver.spec.ts b/packages/goal/goal-round-driver/tests/goal-round-driver.spec.ts index c7c5ff41f6..e9b9edc481 100644 --- a/packages/goal/goal-round-driver/tests/goal-round-driver.spec.ts +++ b/packages/goal/goal-round-driver/tests/goal-round-driver.spec.ts @@ -8,10 +8,17 @@ import GoalService, { GoalId } from '@deepseek-ai/dsh-goal' import type { GoalView } from '@deepseek-ai/dsh-goal' import { createUserMessage, LlmAdapter, LlmError } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import type { UserMessage } from '@deepseek-ai/dsh-session' import * as goalSession from '../src/index.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + type ScriptEntry = StreamChunk[] | Error | 'hang' | ((options: GenerateOptions) => StreamChunk[]) /** Small request-recording adapter with controllable failure and cancellation. */ @@ -481,7 +488,7 @@ describe('same-session goal driving', () => { const test = await harness([textResponse('side contexts'), textResponse('revised goal')]) const claimedContext = createUserMessage({ content: [{ type: 'text', text: 'claimed context to restore' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) const roundZeroContext = createUserMessage({ content: [{ type: 'text', text: 'obsolete goal context' }], @@ -489,11 +496,11 @@ describe('same-session goal driving', () => { }) const queuedStepContext = createUserMessage({ content: [{ type: 'text', text: 'context already queued for the next step' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) const queuedTurnContext = createUserMessage({ content: [{ type: 'text', text: 'context already queued for the next turn' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) let staged = false const stopInserted = onInboxMessage(test.ctx, test.agent, (message) => { diff --git a/packages/goal/goal/tests/goal.spec.ts b/packages/goal/goal/tests/goal.spec.ts index 5bf72d11bf..06e31d7196 100644 --- a/packages/goal/goal/tests/goal.spec.ts +++ b/packages/goal/goal/tests/goal.spec.ts @@ -3,6 +3,7 @@ import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { agentEvents } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, HarnessError } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, type UserMessage } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import GoalService, { @@ -14,6 +15,13 @@ import GoalService, { import type { GoalChangeMeta, GoalRef, GoalSnapshotChangeMeta } from '@deepseek-ai/dsh-goal' import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + 'ordinary-user-message': { kind: 'ordinary-user-message' } & ContextFormed + } +} + interface StubAgent { agent: Agent session: Session @@ -618,7 +626,7 @@ describe('goal replay validation', () => { expect(foldGoal(session.snapshotEvents())).toMatchObject({ goal: { id: change.goal.id, revision: 1 } }) const message = createUserMessage({ content: [{ type: 'text', text: 'unrelated pending context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) const inbox = stubAgentForSession(session).agent.inbox inbox.append('next-step', message) @@ -639,10 +647,10 @@ describe('goal replay validation', () => { const session = Session.create(SessionId('unrelated')) appendInjection(session, createUserMessage({ content: [{ type: 'text', text: 'other' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })) expect(foldGoal(session.snapshotEvents())).toEqual({ roundsStarted: 0 }) - const source = { kind: 'plugin', plugin: 'ordinary-user-message' } as const + const source = { kind: 'ordinary-user-message' } as const const turn = nextTurn(session) session.append('turn/start', { turn }) session.append('user/message', createUserMessage({ diff --git a/packages/goal/goal/tests/projection.spec.ts b/packages/goal/goal/tests/projection.spec.ts index 7a9d85d844..227da38ad8 100644 --- a/packages/goal/goal/tests/projection.spec.ts +++ b/packages/goal/goal/tests/projection.spec.ts @@ -13,6 +13,7 @@ import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { agentEvents } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' import type { Session } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' @@ -20,6 +21,12 @@ import GoalService, { GoalId, applyGoalProjection, foldGoal, goalProjectionDefin import type { GoalProjection, GoalProjectionState, GoalRef } from '@deepseek-ai/dsh-goal' import { unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + interface Bench { ctx: Context session: Session @@ -132,10 +139,11 @@ describe('goal projection unit', () => { start: 0, inserted: [createUserMessage({ content: [{ type: 'text', text: 'unrelated pending context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], }) + expect(bench.tailValues().goal).toBeNull() expect(foldGoal(bench.session.snapshotEvents()).goal).toBeUndefined() }) diff --git a/packages/goal/tool-goal/src/index.ts b/packages/goal/tool-goal/src/index.ts index a63f066aa4..c706741c5a 100644 --- a/packages/goal/tool-goal/src/index.ts +++ b/packages/goal/tool-goal/src/index.ts @@ -9,6 +9,13 @@ import z from '@deepseek-ai/schemastery' import { GoalId } from '@deepseek-ai/dsh-goal' import type { GoalRef, GoalView } from '@deepseek-ai/dsh-goal' import { boundContextSummary, createUserMessage, HarnessError } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'tool-goal': { kind: 'tool-goal' } & ContextFormed + } +} + import { defineTool } from '@deepseek-ai/dsh-tools' import type { GenericCallView } from '@deepseek-ai/dsh-tools' import { @@ -323,8 +330,7 @@ export function apply(ctx: Context, config: Config): void { ? renderWrapupContext(goal.objective) : renderWrapupContext(goal.objective, args.blocked_reason as string), source: { - kind: 'plugin', - plugin: 'tool-goal', + kind: 'tool-goal', form: 'notice', summary: boundContextSummary(`${args.action as string}: ${goal.objective}`), }, diff --git a/packages/goal/tool-goal/tests/tool-goal.spec.ts b/packages/goal/tool-goal/tests/tool-goal.spec.ts index 50949298ba..ecc7822bce 100644 --- a/packages/goal/tool-goal/tests/tool-goal.spec.ts +++ b/packages/goal/tool-goal/tests/tool-goal.spec.ts @@ -8,6 +8,7 @@ import GoalService, { GoalId } from '@deepseek-ai/dsh-goal' import type { GoalRef } from '@deepseek-ai/dsh-goal' import { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' import type { MessageSource } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SESSION_FORMAT_VERSION, Session, @@ -21,6 +22,12 @@ import type { ToolExecutionResult } from '@deepseek-ai/dsh-tools' import * as toolGoal from '@deepseek-ai/dsh-tool-goal' import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal interface StubAgent { @@ -249,7 +256,7 @@ describe('goal tool execution authority', () => { expect(driverless.error?.info?.code).toBe('GOAL_TOOL_DRIVER_REQUIRED') closeTurn(root, 1) - openTurn(root, { kind: 'plugin', plugin: 'test' }) + openTurn(root, { kind: 'test' }) const nonHuman = await execute(ctx, 'create_goal', { objective: 'forged' }, root.agent) expect(nonHuman.error?.info?.code).toBe('GOAL_TOOL_AUTHORITY_REQUIRED') closeTurn(root, 2) @@ -313,7 +320,7 @@ describe('goal tool execution authority', () => { it('rejects terminal reporting without human input or a current goal round', async () => { const { ctx, root } = await harness() - openTurn(root, { kind: 'plugin', plugin: 'test' }) + openTurn(root, { kind: 'test' }) const result = await execute(ctx, 'update_goal', { goal_id: 'goal-missing', revision: 1, action: 'complete', }, root.agent) @@ -418,8 +425,7 @@ describe('goal tool state transitions', () => { const contexts = complete.additionalContexts ?? [] expect(contexts).toHaveLength(1) expect(contexts[0]?.source).toEqual({ - kind: 'plugin', - plugin: 'tool-goal', + kind: 'tool-goal', form: 'notice', summary: 'complete: pause cleanly', }) diff --git a/packages/guard/repeat-tool-reminder/src/index.ts b/packages/guard/repeat-tool-reminder/src/index.ts index dc7ad52834..a79722aad0 100644 --- a/packages/guard/repeat-tool-reminder/src/index.ts +++ b/packages/guard/repeat-tool-reminder/src/index.ts @@ -10,6 +10,13 @@ import type { Context } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'repeat-tool-reminder': { kind: 'repeat-tool-reminder' } & ContextFormed + } +} + import type { MessageSource } from '@deepseek-ai/dsh-llm' import type { UserMessage } from '@deepseek-ai/dsh-session' import type { PostToolDecision, ToolExecution } from '@deepseek-ai/dsh-tools' @@ -50,11 +57,11 @@ export const Config: z = z.object({ }) /** - * The `{kind:'plugin'}` source stamped on every reminder this guard injects — - * the label is load-bearing (an unlabeled context would render as a user - * prompt in derived history). + * The `{kind:'repeat-tool-reminder'}` producer source stamped on every reminder + * this guard injects — the label is load-bearing (an unlabeled context would + * render as a user prompt in derived history). */ -const PLUGIN_SOURCE: MessageSource = { kind: 'plugin', plugin: 'repeat-tool-reminder' } +const REMINDER_SOURCE: MessageSource = { kind: 'repeat-tool-reminder' } /** * The gentle first-threshold reminder. Keyed to `thresholds[0]`, not a literal @@ -202,7 +209,7 @@ export function apply(ctx: Context, config: Config): void { : detailedReminder(exec.name, count, previewArguments(canonical, argumentsPreviewChars)) return createUserMessage({ content: [{ type: 'text', text }], - source: { ...PLUGIN_SOURCE, form: 'notice', summary: `${exec.name} × ${count}` }, + source: { ...REMINDER_SOURCE, form: 'notice', summary: `${exec.name} × ${count}` }, }) } diff --git a/packages/guard/repeat-tool-reminder/tests/repeat-tool-reminder.spec.ts b/packages/guard/repeat-tool-reminder/tests/repeat-tool-reminder.spec.ts index 4c505d6cf0..ccaad2300b 100644 --- a/packages/guard/repeat-tool-reminder/tests/repeat-tool-reminder.spec.ts +++ b/packages/guard/repeat-tool-reminder/tests/repeat-tool-reminder.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' import type { Agent } from '@deepseek-ai/dsh-agent' @@ -10,6 +11,12 @@ import * as RepeatToolGuard from '@deepseek-ai/dsh-repeat-tool-reminder' import type { Config } from '@deepseek-ai/dsh-repeat-tool-reminder' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal /** @@ -48,8 +55,7 @@ function reminders(agent: Agent): { text: string; source: unknown }[] { // The reminder is a `notice`-form context; its summary names the repeated // call so a reader sees it without expanding the row. const guardSource = (tool: string, count: number) => ({ - kind: 'plugin', - plugin: 'repeat-tool-reminder', + kind: 'repeat-tool-reminder', form: 'notice', summary: `${tool} × ${count}`, }) @@ -315,7 +321,7 @@ describe('fold onto the downstream decision', () => { kind: 'block' as const, feedback: [{ type: 'text' as const, text: 'nope' }], additionalContexts: [createUserMessage({ - content: [{ type: 'text' as const, text: 'downstream-ctx' }], source: { kind: 'plugin' as const, plugin: 'test' }, + content: [{ type: 'text' as const, text: 'downstream-ctx' }], source: { kind: 'test' as const }, })], })) const adapter = new MockAdapter([ @@ -332,14 +338,14 @@ describe('fold onto the downstream decision', () => { expect(found).toHaveLength(3) // Only the repeated call adds guard context; downstream source fields survive. expect(found[0]!.text).toBe('downstream-ctx') - expect(found[0]!.source).toEqual({ kind: 'plugin', plugin: 'test' }) + expect(found[0]!.source).toEqual({ kind: 'test' }) expect(found[1]!.text).toContain('repeating the exact same tool call') expect(found[1]!.source).toEqual(guardSource('probe', 2)) - expect(found[2]).toEqual({ text: 'downstream-ctx', source: { kind: 'plugin', plugin: 'test' } }) + expect(found[2]).toEqual({ text: 'downstream-ctx', source: { kind: 'test' } }) // The block's feedback reached the tool result unchanged. const results = agent.session.snapshotEvents().filter((e): e is SessionEvent<'tool/result'> => e.type === 'tool/result') - expect(results.every(r => r.data.message.content[0].isError)).toBe(true) - expect(results[1]!.data.message.content[0].content).toEqual([{ type: 'text', text: 'nope' }]) + expect(results.every(r => r.data.message.isError)).toBe(true) + expect(results[1]!.data.message.content).toEqual([{ type: 'text', text: 'nope' }]) }) it('preserves a downstream canonical value replacement while folding', async () => { @@ -362,7 +368,7 @@ describe('fold onto the downstream decision', () => { expect(found).toHaveLength(1) expect(found[0]!.text).toContain('repeating the exact same tool call') const results = agent.session.snapshotEvents().filter((e): e is SessionEvent<'tool/result'> => e.type === 'tool/result') - expect(results[1]!.data.message.content[0].content).toEqual([{ type: 'text', text: 'replaced' }]) + expect(results[1]!.data.message.content).toEqual([{ type: 'text', text: 'replaced' }]) }) }) diff --git a/packages/hooks/hooks-claude-code/src/index.ts b/packages/hooks/hooks-claude-code/src/index.ts index 469c1c0dc4..3d5fd95229 100644 --- a/packages/hooks/hooks-claude-code/src/index.ts +++ b/packages/hooks/hooks-claude-code/src/index.ts @@ -14,6 +14,13 @@ import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision, TurnBoundaryProjection } from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-session-projection' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'hooks-claude-code': { kind: 'hooks-claude-code' } & ContextFormed + } +} + import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm' import type { UserMessage } from '@deepseek-ai/dsh-session' import type { PostToolDecision, PreToolDecision, ToolExecution, ToolExecutionResult } from '@deepseek-ai/dsh-tools' @@ -82,8 +89,8 @@ function nextHandlerId(point: string): string { return `claude-code:${point}:${++handlerCounter}` } -/** The `{kind:'plugin'}` source stamped on every context this bridge injects. */ -const PLUGIN_SOURCE: MessageSource = { kind: 'plugin', plugin: 'hooks-claude-code' } +/** The `{kind:'hooks-claude-code'}` producer source stamped on every context this bridge injects. */ +const CONTEXT_SOURCE: MessageSource = { kind: 'hooks-claude-code' } /** The summary cap bounds a persisted event field — a positive integer or the slice misbehaves silently. */ function assertPositiveInteger(name: string, value: number): void { @@ -191,7 +198,7 @@ export function apply(ctx: Context, config: Config): void { function contextFrom(merged: MergedHookOutcome): UserMessage | undefined { if (merged.additionalContext.length === 0) return undefined const content: ContentBlock[] = merged.additionalContext.map(text => ({ type: 'text', text })) - return createUserMessage({ content, source: PLUGIN_SOURCE }) + return createUserMessage({ content, source: CONTEXT_SOURCE }) } /** Prepend one context without flattening source fields or other downstream metadata. */ @@ -271,7 +278,7 @@ export function apply(ctx: Context, config: Config): void { if (merged.decision === 'deny') { // A blocking Stop hook forces continuation. const text = merged.reason ?? 'continue: blocked by Stop hook' - agent.steer(createUserMessage({ content: [{ type: 'text', text }], source: PLUGIN_SOURCE })) + agent.steer(createUserMessage({ content: [{ type: 'text', text }], source: CONTEXT_SOURCE })) } }) diff --git a/packages/hooks/hooks-claude-code/tests/bridge.spec.ts b/packages/hooks/hooks-claude-code/tests/bridge.spec.ts index 68f6c8319d..dab06cabca 100644 --- a/packages/hooks/hooks-claude-code/tests/bridge.spec.ts +++ b/packages/hooks/hooks-claude-code/tests/bridge.spec.ts @@ -129,7 +129,7 @@ describe('hooks-claude-code bridge — UserPromptSubmit', () => { // The injected context reached the model and is recorded with the plugin source. expect(JSON.stringify(adapter.requests[0]!.messages)).toContain('remember: be brief') const ctxMsg = events(agent).find(e => e.type === 'user/message' && e.data.source.kind !== 'user') - expect(ctxMsg?.type === 'user/message' && ctxMsg.data.source).toEqual({ kind: 'plugin', plugin: 'hooks-claude-code' }) + expect(ctxMsg?.type === 'user/message' && ctxMsg.data.source).toEqual({ kind: 'hooks-claude-code' }) }) }) @@ -153,8 +153,8 @@ describe('hooks-claude-code bridge — PreToolUse', () => { expect(ran).toBe(false) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('danger tool blocked'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('danger tool blocked'))).toBe(true) }) it('a PreToolUse hook whose matcher does NOT match leaves the tool alone', async () => { @@ -176,7 +176,7 @@ describe('hooks-claude-code bridge — PreToolUse', () => { expect(ran).toBe(true) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(false) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(false) }) }) @@ -198,8 +198,8 @@ describe('hooks-claude-code bridge — PostToolUse', () => { const result = events(agent).find(e => e.type === 'tool/result') // PostToolUse blocks AFTER the tool ran: the result is rewritten to isError + feedback. - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('output rejected, retry'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('output rejected, retry'))).toBe(true) }) it('a PostToolUse hook printing additionalContext attaches it after the tool result', async () => { @@ -244,8 +244,8 @@ describe('hooks-claude-code bridge — PostToolUse', () => { // No approval service is mounted, so `ask` fails closed: the tool does not run and the result is isError. expect(ran).toBe(false) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('needs approval'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('needs approval'))).toBe(true) }) }) diff --git a/packages/hooks/hooks-claude-code/tests/coverage-cases.ts b/packages/hooks/hooks-claude-code/tests/coverage-cases.ts index a05812666d..8a5a068efa 100644 --- a/packages/hooks/hooks-claude-code/tests/coverage-cases.ts +++ b/packages/hooks/hooks-claude-code/tests/coverage-cases.ts @@ -1,4 +1,5 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync, writeFileSync, chmodSync, existsSync, readFileSync } from 'node:fs' import { tmpdir } from 'node:os' @@ -17,6 +18,12 @@ import SubagentRuntime, { SubagentRunId } from '@deepseek-ai/dsh-subagent' import * as HooksClaude from '@deepseek-ai/dsh-hooks-claude-code' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'policy': { kind: 'policy' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal /** Targeted branch coverage for the CC bridge: option arms, warn paths, no-agent @@ -278,7 +285,7 @@ export function defineCoverageCases(group: CoverageGroup): void { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })) await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('blocked by PreToolUse hook'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('blocked by PreToolUse hook'))).toBe(true) }) it('PostToolUse deny with EMPTY stderr + no context uses the default feedback', async () => { @@ -292,7 +299,7 @@ export function defineCoverageCases(group: CoverageGroup): void { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })) await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('blocked by PostToolUse hook'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('blocked by PostToolUse hook'))).toBe(true) }) it('SubagentStop with no registered child runs the hook cleanly (fire-and-forget)', async () => { @@ -338,7 +345,7 @@ export function defineCoverageCases(group: CoverageGroup): void { await waitForIdle(ctx, agent) // ask (no reason) → degrades to deny with the registry's generic message. expect(ran).toBe(false) - expect(events(agent).some(e => e.type === 'tool/result' && e.data.message.content[0].isError)).toBe(true) + expect(events(agent).some(e => e.type === 'tool/result' && e.data.message.isError)).toBe(true) }) it('a recorded clean exit-0 hook with no stderr omits exitCode-extra/stderrSummary fields', async () => { @@ -408,7 +415,7 @@ export function defineCoverageCases(group: CoverageGroup): void { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })) await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) }) }) @@ -444,8 +451,8 @@ export function defineCoverageCases(group: CoverageGroup): void { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })) await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('bad'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('bad'))).toBe(true) // additionalContext also injected (the block + context arm). expect(events(agent).some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('context too')))).toBe(true) }) @@ -525,7 +532,7 @@ export function defineCoverageCases(group: CoverageGroup): void { content: [{ type: 'text' as const, text: 'rewritten-prompt' }], }, createUserMessage({ content: [{ type: 'text' as const, text: 'from-downstream' }], - source: { kind: 'plugin' as const, plugin: 'policy' }, + source: { kind: 'policy' as const }, })], })) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -540,8 +547,8 @@ export function defineCoverageCases(group: CoverageGroup): void { expect(userMsg?.type === 'user/message' && userMsg.data.content.some(b => b.type === 'text' && b.text === 'rewritten-prompt')).toBe(true) const contexts = events(agent).filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(contexts.map(event => event.type === 'user/message' && event.data.source)).toEqual([ - { kind: 'plugin', plugin: 'policy' }, - { kind: 'plugin', plugin: 'hooks-claude-code' }, + { kind: 'policy' }, + { kind: 'hooks-claude-code' }, ]) }) @@ -559,7 +566,7 @@ export function defineCoverageCases(group: CoverageGroup): void { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })) await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text === 'rewritten-result')).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text === 'rewritten-result')).toBe(true) expect(events(agent).some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('bridge-note')))).toBe(true) }) @@ -574,7 +581,7 @@ export function defineCoverageCases(group: CoverageGroup): void { kind: 'accept' as const, additionalContexts: [createUserMessage({ content: [{ type: 'text' as const, text: 'downstream-note' }], - source: { kind: 'plugin' as const, plugin: 'policy' }, + source: { kind: 'policy' as const }, })], })) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -583,8 +590,8 @@ export function defineCoverageCases(group: CoverageGroup): void { const contexts = events(agent).filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(contexts.map(event => event.type === 'user/message' && event.data.source)).toEqual([ - { kind: 'plugin', plugin: 'hooks-claude-code' }, - { kind: 'plugin', plugin: 'policy' }, + { kind: 'hooks-claude-code' }, + { kind: 'policy' }, ]) }) @@ -603,8 +610,8 @@ export function defineCoverageCases(group: CoverageGroup): void { agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })) await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('downstream-block'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('downstream-block'))).toBe(true) // the bridge's context still landed (folded onto the block) expect(events(agent).some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('bridge-note')))).toBe(true) }) diff --git a/packages/hooks/hooks-codex/src/index.ts b/packages/hooks/hooks-codex/src/index.ts index 037252dcde..1599ceee70 100644 --- a/packages/hooks/hooks-codex/src/index.ts +++ b/packages/hooks/hooks-codex/src/index.ts @@ -17,6 +17,13 @@ import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-session-projection' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'hooks-codex': { kind: 'hooks-codex' } & ContextFormed + } +} + import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm' import type { UserMessage } from '@deepseek-ai/dsh-session' import type { PostToolDecision, PreToolDecision, ToolExecution, ToolExecutionResult } from '@deepseek-ai/dsh-tools' @@ -68,7 +75,7 @@ function nextHandlerId(point: string): string { return `codex:${point}:${++handlerCounter}` } -const PLUGIN_SOURCE: MessageSource = { kind: 'plugin', plugin: 'hooks-codex' } +const CONTEXT_SOURCE: MessageSource = { kind: 'hooks-codex' } /** The summary cap bounds a persisted event field — a positive integer or the slice misbehaves silently. */ function assertPositiveInteger(name: string, value: number): void { @@ -173,7 +180,7 @@ export function apply(ctx: Context, config: Config): void { function contextFrom(merged: MergedHookOutcome): UserMessage | undefined { if (merged.additionalContext.length === 0) return undefined const content: ContentBlock[] = merged.additionalContext.map(text => ({ type: 'text', text })) - return createUserMessage({ content, source: PLUGIN_SOURCE }) + return createUserMessage({ content, source: CONTEXT_SOURCE }) } /** Prepend one context without flattening source fields or other downstream metadata. */ @@ -264,7 +271,7 @@ export function apply(ctx: Context, config: Config): void { // empty stderr) still forces it — fall back to a generic steering line // rather than letting the turn stop. const text = merged.reason ?? 'continue: blocked by Stop hook' - agent.steer(createUserMessage({ content: [{ type: 'text', text }], source: PLUGIN_SOURCE })) + agent.steer(createUserMessage({ content: [{ type: 'text', text }], source: CONTEXT_SOURCE })) } }) } diff --git a/packages/hooks/hooks-codex/tests/bridge.spec.ts b/packages/hooks/hooks-codex/tests/bridge.spec.ts index a910f00e9b..67047d8ba7 100644 --- a/packages/hooks/hooks-codex/tests/bridge.spec.ts +++ b/packages/hooks/hooks-codex/tests/bridge.spec.ts @@ -104,8 +104,8 @@ describe('hooks-codex bridge', () => { expect(ran).toBe(false) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('codex blocked it'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('codex blocked it'))).toBe(true) expect(events(agent).some(e => e.type === 'hook/invoked' && e.data.dialect === 'codex' && e.data.point === 'PreToolUse')).toBe(true) }) diff --git a/packages/hooks/hooks-codex/tests/coverage-cases.ts b/packages/hooks/hooks-codex/tests/coverage-cases.ts index 6eebc5e7c1..80c5e42bd3 100644 --- a/packages/hooks/hooks-codex/tests/coverage-cases.ts +++ b/packages/hooks/hooks-codex/tests/coverage-cases.ts @@ -1,4 +1,5 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync, writeFileSync, chmodSync, existsSync, readFileSync } from 'node:fs' import { tmpdir } from 'node:os' @@ -15,6 +16,12 @@ import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' import * as HooksCodex from '@deepseek-ai/dsh-hooks-codex' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'policy': { kind: 'policy' } & ContextFormed + } +} + const testToolSignal = new AbortController().signal const dirs: string[] = [] @@ -133,7 +140,7 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro content: [{ type: 'text' as const, text: 'rewritten-prompt' }], }, createUserMessage({ content: [{ type: 'text' as const, text: 'from-downstream' }], - source: { kind: 'plugin' as const, plugin: 'policy' }, + source: { kind: 'policy' as const }, })], })) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -144,8 +151,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro expect(req).toContain('rewritten-prompt') const contexts = events(agent).filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(contexts.map(event => event.type === 'user/message' && event.data.source)).toEqual([ - { kind: 'plugin', plugin: 'policy' }, - { kind: 'plugin', plugin: 'hooks-codex' }, + { kind: 'policy' }, + { kind: 'hooks-codex' }, ]) }) }) @@ -161,7 +168,7 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text === 'rewritten-result')).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text === 'rewritten-result')).toBe(true) expect(events(agent).some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('bridge-note')))).toBe(true) }) @@ -175,7 +182,7 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro kind: 'accept' as const, additionalContexts: [createUserMessage({ content: [{ type: 'text' as const, text: 'downstream-note' }], - source: { kind: 'plugin' as const, plugin: 'policy' }, + source: { kind: 'policy' as const }, })], })) const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) @@ -183,8 +190,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro const contexts = events(agent).filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(contexts.map(event => event.type === 'user/message' && event.data.source)).toEqual([ - { kind: 'plugin', plugin: 'hooks-codex' }, - { kind: 'plugin', plugin: 'policy' }, + { kind: 'hooks-codex' }, + { kind: 'policy' }, ]) }) @@ -198,8 +205,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent) const result = events(agent).find(e => e.type === 'tool/result') - expect(result?.type === 'tool/result' && result.data.message.content[0].isError).toBe(true) - expect(result?.type === 'tool/result' && result.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('downstream-block'))).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.isError).toBe(true) + expect(result?.type === 'tool/result' && result.data.message.content.some(b => b.type === 'text' && b.text.includes('downstream-block'))).toBe(true) expect(events(agent).some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('bridge-note')))).toBe(true) }, 10_000) // The real hook subprocess needs startup and teardown headroom under full-suite contention. @@ -224,8 +231,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent) const r = events(agent).find(e => e.type === 'tool/result') - expect(r?.type === 'tool/result' && r.data.message.content[0].isError).toBe(true) - expect(r?.type === 'tool/result' && r.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('blocked by PostToolUse hook'))).toBe(true) + expect(r?.type === 'tool/result' && r.data.message.isError).toBe(true) + expect(r?.type === 'tool/result' && r.data.message.content.some(b => b.type === 'text' && b.text.includes('blocked by PostToolUse hook'))).toBe(true) }) it('PostToolUse additionalContext (clean exit) is attached after the result', async () => { @@ -426,7 +433,7 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent) const r = events(agent).find(e => e.type === 'tool/result') - expect(r?.type === 'tool/result' && r.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('blocked by PreToolUse hook'))).toBe(true) + expect(r?.type === 'tool/result' && r.data.message.content.some(b => b.type === 'text' && b.text.includes('blocked by PreToolUse hook'))).toBe(true) }) it('PostToolUse block AND additionalContext are surfaced together', async () => { @@ -438,8 +445,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro const agent = await ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' }) agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent) const r = events(agent).find(e => e.type === 'tool/result') - expect(r?.type === 'tool/result' && r.data.message.content[0].isError).toBe(true) - expect(r?.type === 'tool/result' && r.data.message.content[0].content.some(b => b.type === 'text' && b.text.includes('bad'))).toBe(true) + expect(r?.type === 'tool/result' && r.data.message.isError).toBe(true) + expect(r?.type === 'tool/result' && r.data.message.content.some(b => b.type === 'text' && b.text.includes('bad'))).toBe(true) expect(events(agent).some(e => e.type === 'user/message' && e.data.source.kind !== 'user' && e.data.content.some(b => b.type === 'text' && b.text.includes('ctx too')))).toBe(true) }) diff --git a/packages/interaction/user-approval/src/index.ts b/packages/interaction/user-approval/src/index.ts index 8a5f506bf1..9a14f04d0b 100644 --- a/packages/interaction/user-approval/src/index.ts +++ b/packages/interaction/user-approval/src/index.ts @@ -9,6 +9,13 @@ import { Context, Service } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, type ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'user-approval': { kind: 'user-approval' } & ContextFormed + } +} + import { scopeTarget } from '@deepseek-ai/dsh-scope' import type { Session } from '@deepseek-ai/dsh-session' import { SessionSeq } from '@deepseek-ai/dsh-session' @@ -183,7 +190,7 @@ export class ApprovalService extends Service { type: 'text', text: `The approval policy changed from "${previous}" to "${policy}" (changed by the user).`, }], - source: { kind: 'plugin', plugin: 'user-approval' }, + source: { kind: 'user-approval' }, })) } diff --git a/packages/interaction/user-approval/tests/approval.spec.ts b/packages/interaction/user-approval/tests/approval.spec.ts index 70e1abcf4e..0ec3b9580b 100644 --- a/packages/interaction/user-approval/tests/approval.spec.ts +++ b/packages/interaction/user-approval/tests/approval.spec.ts @@ -471,7 +471,7 @@ describe('approval policy (the approval/policy fold)', () => { type: 'text', text: 'The approval policy changed from "ask" to "never" (changed by the user).', }], - source: { kind: 'plugin', plugin: 'user-approval' }, + source: { kind: 'user-approval' }, }) }) diff --git a/packages/jobs/tool-jobs/src/index.ts b/packages/jobs/tool-jobs/src/index.ts index 277d7181a4..210005be6a 100644 --- a/packages/jobs/tool-jobs/src/index.ts +++ b/packages/jobs/tool-jobs/src/index.ts @@ -10,12 +10,18 @@ import type { Context } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' import { boundContextSummary, createUserMessage, type ContentBlock } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { TextRetainer } from '@deepseek-ai/dsh-output-retention' import { defineTool } from '@deepseek-ai/dsh-tools' import type { GenericCallView, ToolDefinition, ToolExecution } from '@deepseek-ai/dsh-tools' import { JobId } from '@deepseek-ai/dsh-jobs' import type { JobSnapshot } from '@deepseek-ai/dsh-jobs' import type { Agent } from '@deepseek-ai/dsh-agent' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'tool-jobs': { kind: 'tool-jobs' } & ContextFormed + } +} export const name = 'tool-jobs' export const inject = ['tools', 'jobs', 'systemPrompt'] @@ -283,8 +289,7 @@ export function apply(ctx: Context, config: Config): void { text: fitCompletionNotice(snapshot), }], source: { - kind: 'plugin', - plugin: 'tool-jobs', + kind: 'tool-jobs', form: 'notice', summary: completionSummary(snapshot), }, diff --git a/packages/jobs/tool-jobs/tests/tool-jobs.spec.ts b/packages/jobs/tool-jobs/tests/tool-jobs.spec.ts index 6f32878207..f7c543c024 100644 --- a/packages/jobs/tool-jobs/tests/tool-jobs.spec.ts +++ b/packages/jobs/tool-jobs/tests/tool-jobs.spec.ts @@ -672,7 +672,7 @@ describe('completion notice delivery', () => { emitAgentEvent(ctx, owner, 'agent/inbox/claimed', { message: createUserMessage({ content: [{ type: 'text', text: 'background job bash-1 finished' }], - source: { kind: 'plugin', plugin: 'tool-jobs', form: 'notice', summary: 'bash' }, + source: { kind: 'tool-jobs', form: 'notice', summary: 'bash' }, }), turn: 1, }) @@ -697,8 +697,7 @@ describe('completion notices', () => { role: 'user', content: [{ type: 'text', text: 'background job bash-1 (bash: pnpm test) finished [status: completed, exit code: 0]. Read its output with job_output.' }], source: { - kind: 'plugin', - plugin: 'tool-jobs', + kind: 'tool-jobs', form: 'notice', summary: 'bash pnpm test [status: completed, exit code: 0]', }, @@ -728,8 +727,7 @@ describe('completion notices', () => { // The label and status detail are unbounded caller text, so the durable // one-line account caps itself rather than committing their full length. source: { - kind: 'plugin', - plugin: 'tool-jobs', + kind: 'tool-jobs', form: 'notice', summary: `subagent ${'x'.repeat(110)}…`, }, diff --git a/packages/llm/llm-deepseek/README.i18n.yaml b/packages/llm/llm-deepseek/README.i18n.yaml index cc43d12297..607a582e94 100644 --- a/packages/llm/llm-deepseek/README.i18n.yaml +++ b/packages/llm/llm-deepseek/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/llm/llm-deepseek/README.md -README.md: 33a76a316fd6f89e5d011ab3aa7a933331bd1e7b -README.zh.md: dbc7282140268985f215efcac0b4e602cd5b0e44 +README.md: 3dfd14b888c98196927e280a2c1e7cbf1d499e3a +README.zh.md: 7442caf49d491c0aac76a6b7f20fbfc767dc856b diff --git a/packages/llm/llm-deepseek/README.md b/packages/llm/llm-deepseek/README.md index 33a76a316f..3dfd14b888 100644 --- a/packages/llm/llm-deepseek/README.md +++ b/packages/llm/llm-deepseek/README.md @@ -27,6 +27,8 @@ Stream DeepSeek models through `deepseek-official` with Messages by default, or Mount this plugin when a composition streams DeepSeek models through the harness LLM service. It registers the single `deepseek-official` route and resolves connection facts per request, so a composition entry plus an optional user settings section drive the whole adapter. +Both protocols accept the LLM service's [request-only user inputs](../llm/README.md#use-this-package) alongside durable history; omitting request-only identity and attribution does not alter provider content. + ### When to choose it Choose this adapter for DeepSeek's official API or a gateway that supports the selected protocol through `baseURL`. Choose `dsh-llm-pi-ai` when the same composition also routes other providers or hand-declared gateways through pi-ai's catalogs; the two adapters can be mounted together because their route names do not collide. Registering any other adapter for `deepseek-official` fails with `DUPLICATE_ADAPTER`. diff --git a/packages/llm/llm-deepseek/README.zh.md b/packages/llm/llm-deepseek/README.zh.md index dbc7282140..7442caf49d 100644 --- a/packages/llm/llm-deepseek/README.zh.md +++ b/packages/llm/llm-deepseek/README.zh.md @@ -27,6 +27,8 @@ kind: "package-reference" 当组合需要通过 harness LLM(大语言模型)服务流式调用 DeepSeek 模型时挂载本插件。它注册唯一的 `deepseek-official` 路由,并按请求解析连接事实,因此组合条目加可选用户设置分节即可驱动整个适配器。 +两种协议都接受 LLM 服务的[仅供请求使用的 user 输入](../llm/README.zh.md#use-this-package),并可将其与持久历史混用;省略请求输入的身份与来源不会改变提供方内容。 + ### 何时选择 面向 DeepSeek 官方 API,或通过 `baseURL` 连接支持所选协议的网关时,选择本适配器。当同一组合还要通过 pi-ai 目录路由其他提供方或手工声明的网关时,选择 `dsh-llm-pi-ai`;两个适配器可以同时挂载,因为它们的路由名不冲突。为 `deepseek-official` 注册任何其他适配器会以 `DUPLICATE_ADAPTER` 失败。 diff --git a/packages/llm/llm-deepseek/src/protocols/chat-completions/adapter.ts b/packages/llm/llm-deepseek/src/protocols/chat-completions/adapter.ts index 3d2e50ea45..77d2bf6ca5 100644 --- a/packages/llm/llm-deepseek/src/protocols/chat-completions/adapter.ts +++ b/packages/llm/llm-deepseek/src/protocols/chat-completions/adapter.ts @@ -50,7 +50,6 @@ function collectImageRefs( ): void { for (const block of content) { if (block.type === 'image' && block.offloaded !== true) refs.set(block.attachment.attachmentId, block.attachment) - else if (block.type === 'tool-result') collectImageRefs(block.content, refs) } } diff --git a/packages/llm/llm-deepseek/src/protocols/chat-completions/serialize.ts b/packages/llm/llm-deepseek/src/protocols/chat-completions/serialize.ts index 62e79bf94c..803e4c6877 100644 --- a/packages/llm/llm-deepseek/src/protocols/chat-completions/serialize.ts +++ b/packages/llm/llm-deepseek/src/protocols/chat-completions/serialize.ts @@ -1,13 +1,14 @@ /** * Serialize harness messages into DeepSeek chat completions. Text-only * requests retain string user content; the image path resolves durable - * attachments into ordered file-id or inline parts. Tool-result images follow their - * string-only tool messages in a separate user message. + * attachments into ordered file-id or inline parts. Tool-role messages map to + * string-only `tool` wire messages; their image parts follow in one shared + * trailing user message. * @module dsh-llm-deepseek/serialize */ import { contentHasImage, IMAGE_OFFLOAD_REQUIRED_CODE, LlmError, offloadedImageText, projectOffloadedImages, requestImageHandleText, requiredImageOffload } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, GenerateOptions, ImageAttachmentAccessResolver, Message } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, GenerateOptions, ImageAttachmentAccessResolver, Message, RequestMessage } from '@deepseek-ai/dsh-llm' import type { ImageAttachmentRef, RequestImageAttachment } from '@deepseek-ai/dsh-attachment' import type { WireImageContentPart, @@ -91,8 +92,8 @@ function resolveThinking(options: GenerateOptions, defaults: RequestDefaults): R return defaults.thinking === undefined ? {} : { thinking: defaults.thinking } } -/** Join the text blocks of a message (used for user/tool-result content). */ -function flattenText(blocks: ContentBlock[]): string { +/** Join the text blocks of a message (used for user and tool-role content). */ +function flattenText(blocks: readonly ContentBlock[]): string { return blocks .filter(block => block.type === 'text') .map(block => block.text) @@ -106,10 +107,20 @@ function assertTextOnly(blocks: readonly ContentBlock[]): void { } } -/** Reject roles whose DeepSeek history format cannot carry image input. */ -function assertSupportedImageRoles(messages: readonly Message[]): void { +/** Reject developer history before text serialization or image offloading. */ +function assertSupportedRole(message: RequestMessage): void { + // Developer history is persisted for V4; provider serialization is intentionally deferred. + if (message.role === 'developer') throw new LlmError('Developer messages are not supported yet', 'UNSUPPORTED_CONTENT') + if (message.content.some(block => block.type === 'tool-addition' || block.type === 'tool-removal')) { + throw new LlmError('Tool-change blocks require developer role', 'UNSUPPORTED_CONTENT') + } +} + +/** Reject unsupported roles, tool-change blocks, and image roles before history conversion. */ +function assertSupportedHistory(messages: readonly RequestMessage[]): void { for (const message of messages) { - if (message.role !== 'user' && contentHasImage(message.content)) { + assertSupportedRole(message) + if (message.role !== 'user' && message.role !== 'tool' && contentHasImage(message.content)) { throw new LlmError( `The DeepSeek chat-completions adapter cannot represent image content in a ${message.role} message.`, 'UNSUPPORTED_CONTENT', @@ -154,7 +165,7 @@ async function imageParts( return [imageHandle(block.attachment, version, images.resolveImageAccess, precededByContent), image] } -/** Convert user or nested tool-result blocks into ordered wire parts. */ +/** Convert one message's content blocks into ordered wire parts. */ async function contentParts( blocks: readonly ContentBlock[], images: ImageSerializationOptions, @@ -171,9 +182,6 @@ async function contentParts( nextImage.value += 1 parts.push(...await imageParts(block, images, { message, image: nextImage.value }, parts.length > 0)) break - case 'tool-result': - parts.push(...await contentParts(block.content, images, message, nextImage)) - break default: // Other merge-extensible blocks are not DeepSeek user-input vocabulary. break @@ -229,16 +237,16 @@ function serializeAssistant(message: Message): WireMessage { } /** - * Serialize the conversation. `tool-result` blocks become standalone - * `{role: 'tool'}` messages; the harness puts each tool result in its own - * user-role message, so a mixed user message contributes its text first and - * its tool results as separate wire messages after. + * Serialize the conversation. Tool-role messages map one-to-one onto + * `{role: 'tool'}` wire messages; user messages contribute their text as a + * plain `{role: 'user'}` wire message. * @param messages - the harness conversation, in order. - * @returns the wire messages; order preserved, each tool result expanded into its own entry. + * @returns the wire messages; order preserved. */ -export function serializeMessages(messages: Message[]): WireMessage[] { +export function serializeMessages(messages: RequestMessage[]): WireMessage[] { const wire: WireMessage[] = [] for (const message of messages) { + assertSupportedRole(message) assertTextOnly(message.content) if (message.role === 'system') { wire.push({ role: 'system', content: flattenText(message.content) }) @@ -248,38 +256,34 @@ export function serializeMessages(messages: Message[]): WireMessage[] { wire.push(serializeAssistant(message)) continue } - // user role: tool results ride in user messages in the harness - // vocabulary, but DeepSeek wants them as role:'tool' messages. - const toolResults = message.content.filter(block => block.type === 'tool-result') - const text = flattenText(message.content) - if (text.length > 0 || toolResults.length === 0) { - wire.push({ role: 'user', content: text }) - } - for (const result of toolResults) { + if (message.role === 'tool') { wire.push({ role: 'tool', - tool_call_id: result.toolCallId, + tool_call_id: message.toolCallId, // Empty tool output still needs SOME content on the wire. - content: flattenText(result.content) || '(no output)', + content: flattenText(message.content) || '(no output)', }) + continue } + // User text always lands on the wire, including empty ones. + wire.push({ role: 'user', content: flattenText(message.content) }) } return wire } /** * Serialize image-capable history after resolving durable attachments. - * Consecutive tool results keep string `tool` messages and share one following - * user message containing their images. + * Consecutive tool messages keep string `tool` wire messages and share one + * following user message containing their images. * @param messages - request history whose offloaded occurrences are already placeholder text. * @param images - prepared request versions, one provider representation, and its budget. * @returns ordered DeepSeek wire messages. */ export async function serializeMessagesWithImages( - messages: readonly Message[], + messages: readonly RequestMessage[], images: ImageSerializationOptions, ): Promise { - assertSupportedImageRoles(messages) + assertSupportedHistory(messages) const wire: WireMessage[] = [] let pendingToolImages: WireImageContentPart[] = [] const flushToolImages = (): void => { @@ -303,30 +307,23 @@ export async function serializeMessagesWithImages( wire.push(serializeAssistant(message)) continue } - - const regular = message.content.filter(block => block.type !== 'tool-result') - const toolResults = message.content.filter((block): block is Extract => ( - block.type === 'tool-result' - )) - const content = userContent(await contentParts(regular, images, messageIndex + 1, nextImage)) - if (content.length > 0 || toolResults.length === 0) { - flushToolImages() - wire.push({ - role: 'user', - content, - }) - } - for (const result of toolResults) { - const parts = await contentParts(result.content, images, messageIndex + 1, nextImage) + if (message.role === 'tool') { + const parts = await contentParts(message.content, images, messageIndex + 1, nextImage) const imageParts = parts.filter((part): part is WireImageContentPart => part.type !== 'text') const text = parts.filter(part => part.type === 'text').map(part => part.text).join('') wire.push({ role: 'tool', - tool_call_id: result.toolCallId, + tool_call_id: message.toolCallId, content: text || '(no output)', }) pendingToolImages.push(...imageParts) + continue } + // User text serializes as a user message, including empty content. This + // keeps the image-capable route aligned with the text-only route. + const content = userContent(await contentParts(message.content, images, messageIndex + 1, nextImage)) + flushToolImages() + wire.push({ role: 'user', content }) } flushToolImages() return wire @@ -338,6 +335,10 @@ function requestWithMessages( messages: WireMessage[], defaults: RequestDefaults, ): WireRequest { + // Deferred definitions are persisted for V4; provider loading is intentionally deferred. + if (options.tools?.some(tool => tool.deferLoading === true)) { + throw new LlmError('Deferred tool loading is not supported yet', 'UNSUPPORTED_CONTENT') + } const tools: WireTool[] | undefined = options.tools?.map(tool => ({ type: 'function', function: { @@ -390,7 +391,7 @@ export function serializeRequest( * failure names how many more oldest retained occurrences need durable * omission before the request can be retried. */ -function assertRetainedImagesFit(messages: readonly Message[], images: ImageSerializationOptions): void { +function assertRetainedImagesFit(messages: readonly RequestMessage[], images: ImageSerializationOptions): void { const representation = images.representation.kind === 'file' ? 'raw' : 'base64' const offloadImages = requiredImageOffload(messages, { representation, @@ -428,7 +429,7 @@ export async function serializeRequestWithImages( images: ImageSerializationOptions, defaults: RequestDefaults = {}, ): Promise { - assertSupportedImageRoles(options.messages) + assertSupportedHistory(options.messages) assertRetainedImagesFit(options.messages, images) const requestMessages = projectOffloadedImages( options.messages, diff --git a/packages/llm/llm-deepseek/src/protocols/messages/images.ts b/packages/llm/llm-deepseek/src/protocols/messages/images.ts index 64b0933b12..f2f32f003e 100644 --- a/packages/llm/llm-deepseek/src/protocols/messages/images.ts +++ b/packages/llm/llm-deepseek/src/protocols/messages/images.ts @@ -2,7 +2,7 @@ import type { AttachmentStore, ImageAttachmentRef, RequestImageAttachment } from '@deepseek-ai/dsh-attachment' import { contentHasImage, IMAGE_OFFLOAD_REQUIRED_CODE, LlmError, offloadedImageText, projectOffloadedImages, requiredImageOffload } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, ImageAttachmentAccessResolver, Message } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, ImageAttachmentAccessResolver, RequestMessage } from '@deepseek-ai/dsh-llm' import type { DeepSeekConnectionOptions as Connection } from '../../common/types.ts' import { resolveRequestImageTarget } from '../../common/request-pricing.ts' import type { DeepSeekFileId } from '../../common/file-id.ts' @@ -23,7 +23,6 @@ function bounds(connection: Connection, representation: 'raw' | 'base64') { function* imageRefs(blocks: readonly ContentBlock[]): Generator { for (const block of blocks) { if (block.type === 'image') yield block.attachment - else if (block.type === 'tool-result') yield* imageRefs(block.content) } } @@ -37,9 +36,9 @@ function* imageRefs(blocks: readonly ContentBlock[]): Generator }> { +): Promise<{ messages: readonly RequestMessage[]; versions: Map }> { const versions = new Map() const messages = projectOffloadedImages(history, ref => offloadedImageText(ref, access(ref))) if (!messages.some(message => contentHasImage(message.content))) return { messages, versions } @@ -47,7 +46,7 @@ export async function prepareImages( if (model?.inputModalities?.includes('image') !== true || attachments === undefined) { throw new LlmError('DeepSeek Messages image input requires a vision model and attachment service', 'UNSUPPORTED_CONTENT') } - if (messages.some(message => message.role !== 'user' && contentHasImage(message.content))) { + if (messages.some(message => message.role !== 'user' && message.role !== 'tool' && contentHasImage(message.content))) { throw new LlmError('DeepSeek Messages supports images only in user messages and tool results', 'UNSUPPORTED_CONTENT') } for (const message of messages) { @@ -68,16 +67,16 @@ export async function prepareImages( * @returns unchanged history within both byte and image-count limits. */ export function inlineImages( - messages: readonly Message[], versions: ReadonlyMap, + messages: readonly RequestMessage[], versions: ReadonlyMap, connection: Connection, -): readonly Message[] { +): readonly RequestMessage[] { assertImagesFit(messages, versions, connection, 'base64') return messages } /** Count additional oldest occurrences requiring durable offload at their exact represented bytes. */ function assertImagesFit( - messages: readonly Message[], versions: ReadonlyMap, + messages: readonly RequestMessage[], versions: ReadonlyMap, connection: Connection, representation: 'raw' | 'base64', ): void { const offloadImages = requiredImageOffload(messages, bounds(connection, representation), @@ -98,7 +97,7 @@ function assertImagesFit( * @returns ids keyed by durable attachment identity. */ export async function prepareFileIds( - messages: readonly Message[], versions: ReadonlyMap, files: RequestFiles, + messages: readonly RequestMessage[], versions: ReadonlyMap, files: RequestFiles, ): Promise> { const ids = new Map() for (const [index, message] of messages.entries()) { diff --git a/packages/llm/llm-deepseek/src/protocols/messages/serialize.ts b/packages/llm/llm-deepseek/src/protocols/messages/serialize.ts index 41d3f3bb4a..78448e6e51 100644 --- a/packages/llm/llm-deepseek/src/protocols/messages/serialize.ts +++ b/packages/llm/llm-deepseek/src/protocols/messages/serialize.ts @@ -1,7 +1,7 @@ /** Map system snapshots and conversation turns to Messages using the configured route capability. */ import { LlmError, requestImageHandleText } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, GenerateOptions, ImageAttachmentAccessResolver, Message } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, GenerateOptions, ImageAttachmentAccessResolver, Message, RequestMessage } from '@deepseek-ai/dsh-llm' import type { ImageAttachmentRef, RequestImageAttachment } from '@deepseek-ai/dsh-attachment' import type { DeepSeekConnectionOptions as Connection } from '../../common/types.ts' import type { DeepSeekFileId } from '../../common/file-id.ts' @@ -51,7 +51,7 @@ function assistant(message: Message, model: string, onReplayDegrade?: (reason: s * @returns the Messages API JSON body. */ export function serialize( - options: GenerateOptions, connection: Connection, history: readonly Message[], + options: GenerateOptions, connection: Connection, history: readonly RequestMessage[], images: ReadonlyMap, access: ImageAttachmentAccessResolver, onReplayDegrade?: (reason: string) => void, fileIds?: ReadonlyMap, @@ -83,7 +83,14 @@ export function serialize( if (messages.at(-1)?.role !== 'user') return unsupported('system update without a preceding user or tool-result turn') messages.push(...systemUpdates.splice(0)) } + // Deferred definitions are persisted for V4; provider loading is intentionally deferred. + if (options.tools?.some(tool => tool.deferLoading === true)) return unsupported('deferred tool loading') for (const message of history) { + // Developer history is persisted for V4; provider serialization is intentionally deferred. + if (message.role === 'developer') return unsupported('developer message') + if (message.content.some(block => block.type === 'tool-addition' || block.type === 'tool-removal')) { + return unsupported('tool-change blocks outside developer messages') + } if (message.role === 'system') { const texts = message.content.filter(block => block.type === 'text') if (texts.length !== message.content.length) return unsupported('non-text system message') @@ -97,14 +104,16 @@ export function serialize( continue } if (message.role === 'assistant') flushSystemUpdates() - const content: WireBlock[] = message.role === 'assistant' ? assistant(message, options.model, onReplayDegrade) : message.content.flatMap((block): WireBlock[] => { - if (block.type !== 'tool-result') return input([block]) - return [{ type: 'tool_result', tool_use_id: block.toolCallId, content: input(block.content), ...block.isError === undefined ? {} : { is_error: block.isError } }] - }) + const content: WireBlock[] = message.role === 'assistant' + ? assistant(message, options.model, onReplayDegrade) + : message.role === 'tool' + ? [{ type: 'tool_result', tool_use_id: message.toolCallId, content: input(message.content), ...message.isError === undefined ? {} : { is_error: message.isError } }] + : message.content.flatMap((block): WireBlock[] => input([block])) if (message.role === 'user' && content.length === 0) continue + const wireRole = message.role === 'tool' ? 'user' : message.role const previous = messages.at(-1) - if (previous?.role === message.role) previous.content.push(...content) - else messages.push({ role: message.role, content }) + if (previous?.role === wireRole) previous.content.push(...content) + else messages.push({ role: wireRole, content }) } flushSystemUpdates() let pending = new Set() diff --git a/packages/llm/llm-deepseek/tests/adapter.e2e.ts b/packages/llm/llm-deepseek/tests/adapter.e2e.ts index 6270d385ca..2a68e915cc 100644 --- a/packages/llm/llm-deepseek/tests/adapter.e2e.ts +++ b/packages/llm/llm-deepseek/tests/adapter.e2e.ts @@ -7,7 +7,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import Loader from '@deepseek-ai/cordis-plugin-loader' import AgentRegistry from '@deepseek-ai/dsh-agent' -import LlmRuntime, { createUserMessage, ToolCallId, ReasoningEffortId, createMessage, createSystemMessage } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createToolResultMessage, createUserMessage, ToolCallId, ReasoningEffortId, createMessage, createSystemMessage } from '@deepseek-ai/dsh-llm' import type { Message, ToolSchema } from '@deepseek-ai/dsh-llm' import AttachmentStore, { AttachmentId, ImageVariantId } from '@deepseek-ai/dsh-attachment' import LocalAttachments from '@deepseek-ai/dsh-attachment-local' @@ -128,7 +128,7 @@ afterEach(async () => { function ask(text: string): Message[] { return [createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'user' }, })] } @@ -163,7 +163,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-deepseek e2e (real API)', () const attachment = await ctx.attachments.saveImage({ data: readFileSync(new URL('fixtures/red.png', import.meta.url)), mediaType: 'image/png' }) const message = ask('What is the dominant color of this image?')[0]! const history: Message[] = [ - createSystemMessage('Answer with one English color word.', 'test'), + createSystemMessage('Answer with one English color word.'), { ...message, content: [...message.content, { type: 'image', attachment }] }, ] const reply = async () => { @@ -173,7 +173,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-deepseek e2e (real API)', () return textOf(response).trim().toLowerCase() } expect(await reply()).toMatch(/^red[.!]?$/) - history.push(createSystemMessage('Reply to every user message with exactly banana.', 'test'), ...ask('Answer now.')) + history.push(createSystemMessage('Reply to every user message with exactly banana.'), ...ask('Answer now.')) expect(await reply()).toBe('banana') history.push(...ask('Answer again.')) expect(await reply()).toBe('banana') @@ -209,7 +209,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-deepseek e2e (real API)', () { type: 'text', text: 'Briefly describe this image.' }, { type: 'image', attachment: attachments.ref }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'user' }, })], maxTokens: 100, }) @@ -335,15 +335,12 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-deepseek e2e (real API)', () ...ask('What is the weather in Paris right now? Use the get_weather tool.'), createMessage({ role: 'assistant', content: first.message.content, - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId(call!.id), - content: [{ type: 'text', text: 'Sunny, 22°C' }], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId(call!.id), + content: [{ type: 'text', text: 'Sunny, 22°C' }], + isError: false, }), ], tools: [weatherTool], @@ -367,7 +364,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-deepseek e2e (real API)', () }) await expect(ctx.llm.resolveModelInfo('deepseek-official', model)) .resolves.toMatchObject({ systemPromptUpdate: 'in-history' }) - const system = (text: string) => createSystemMessage(text, 'test') + const system = (text: string) => createSystemMessage(text) // A nonce before the padding isolates the provider cache across runs and retries. const nonce = randomBytes(16).toString('hex') const padding = Array.from({ length: 40 }, (_, index) => `Rule ${String(index + 1)}: keep every answer short and factual.`).join('\n') @@ -418,7 +415,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-deepseek e2e (real API)', () expect(reusableTokens).toBeLessThanOrEqual(initialTokens) expect(reusableTokens).toBeGreaterThan(0) const assistant = createMessage({ - role: 'assistant', content: first.message.content, source: { kind: 'plugin', plugin: 'test' }, + role: 'assistant', content: first.message.content, source: first.message.source, }) const updated = await assemble(ctx, { diff --git a/packages/llm/llm-deepseek/tests/adapter.spec.ts b/packages/llm/llm-deepseek/tests/adapter.spec.ts index 767c0d5c73..ea6ba2bf8f 100644 --- a/packages/llm/llm-deepseek/tests/adapter.spec.ts +++ b/packages/llm/llm-deepseek/tests/adapter.spec.ts @@ -8,6 +8,7 @@ import type { AttachmentStore, ImageAttachmentRef, RequestImageAttachment } from import { createLaunchEnvironmentSnapshot } from '@deepseek-ai/dsh-launch-environment' import LlmRuntime, { ToolCallId, createUserMessage, CONTEXT_WINDOW_EXCEEDED_CODE, + createToolResultMessage, LlmError, ProviderRequestId, QUOTA_EXCEEDED_CODE, @@ -21,12 +22,19 @@ import DeepSeekLlmApiExtensionRegistry from '@deepseek-ai/dsh-deepseek-llm-api-e import type { PreparedDeepSeekLlmApiExtensions } from '@deepseek-ai/dsh-deepseek-llm-api-extensions' import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek' import { DeepSeekAdapter, resolveAdapterOptions } from '@deepseek-ai/dsh-llm-deepseek' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { httpErrorCode } from '../src/protocols/chat-completions/adapter.ts' import { resolveRequestImageTarget } from '../src/common/request-pricing.ts' import { assemble } from './assemble.ts' import { closeMockServers, mockServer, textEvents } from './mock-server.ts' import type { Behavior } from './mock-server.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const TEST_USER_ID = '00000000-0000-4000-8000-000000000001' as AnonymousUserId let testHome: string @@ -348,7 +356,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-pro', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) expect(result.message.content).toEqual([{ type: 'text', text: 'hello' }]) @@ -392,7 +400,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'text', text: 'describe ' }, { type: 'image', attachment: imageRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -417,6 +425,24 @@ describe('DeepSeekAdapter against a mock server', () => { expect(policies).toEqual([{ width: 1, height: 1, maxBytes: 2 * 1024 * 1024 }]) }) + it('keeps images inside plugin content opaque through adapter.stream', async () => { + const server = await mockServer([{ kind: 'sse', events: textEvents }]) + const attachmentMocks = attachmentStoreOf(ref => Promise.resolve(requestImage(ref))) + const adapter = adapterOf({ baseURL: server.url }, attachmentMocks.store) + await drain(adapter.stream({ provider: 'deepseek-official', model: 'deepseek-v4-pro', messages: [ + createUserMessage({ source: { kind: 'user' }, content: [ + { type: 'plugin:message', + message: { role: 'tool', toolCallId: 'foreign', content: [{ type: 'image', attachment: { ...imageRef } }] }, + } as never, + { type: 'text', text: 'context' }, + ] }), + ] })) + expect(attachmentMocks.readImageRequest).not.toHaveBeenCalled() + expect(server.fileRequests).toHaveLength(0) + expect(server.requests).toHaveLength(1) + expect(server.requests[0]).toMatchObject({ messages: [{ role: 'user', content: 'context' }] }) + }) + it('falls back to one all-base64 request when Files API resolution fails', async () => { const server = await mockServer([{ kind: 'sse', events: textEvents }]) const secondRef = { ...imageRef, attachmentId: AttachmentId(`sha256:${'c'.repeat(64)}`) } @@ -438,7 +464,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: imageRef }, { type: 'image', attachment: secondRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -464,7 +490,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: Array.from({ length: 21 }, () => ({ type: 'image' as const, attachment: imageRef })), - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ code: 'IMAGE_OFFLOAD_REQUIRED', message: expect.stringContaining('11 more') as string }) expect(server.requests).toHaveLength(0) @@ -493,7 +519,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: imageRef }, { type: 'image', attachment: secondRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -525,7 +551,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) await started.promise @@ -557,7 +583,7 @@ describe('DeepSeekAdapter against a mock server', () => { signal: controller.signal, messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) await started.promise @@ -586,7 +612,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ code: 'SERVER', message: 'chat unavailable' }) @@ -616,7 +642,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: old, offloaded: true }, { type: 'image', attachment: recent }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -658,13 +684,10 @@ describe('DeepSeekAdapter against a mock server', () => { }, ], }, attachmentMocks.store) - const nested = createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('image-result'), - content: [{ type: 'image', attachment: imageRef }], - }], - source: { kind: 'plugin', plugin: 'test' }, + const nested = createToolResultMessage({ + callId: ToolCallId('image-result'), + content: [{ type: 'image', attachment: imageRef }], + isError: false, }) await drain(adapter.stream({ provider: 'deepseek-official', model: 'vision-low', messages: [nested] })) @@ -696,7 +719,7 @@ describe('DeepSeekAdapter against a mock server', () => { }, attachments) const messages = [createUserMessage({ content: [{ type: 'image' as const, attachment: imageRef }], - source: { kind: 'plugin' as const, plugin: 'test' }, + source: { kind: 'test' as const }, })] await drain(adapter.stream({ provider: 'deepseek-official', model: 'deepseek-v4-flash-vision-exp', messages })) @@ -731,7 +754,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) } catch (error: unknown) { @@ -763,7 +786,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ message: expect.stringContaining(`normalized image "${imageRef.attachmentId}"`) as string, @@ -799,7 +822,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: imageRef }, { type: 'image', attachment: secondRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ code: 'INVALID_REQUEST', @@ -834,7 +857,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image' as const, attachment: imageRef }], - source: { kind: 'plugin' as const, plugin: 'test' }, + source: { kind: 'test' as const }, })], } @@ -872,7 +895,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -912,7 +935,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: imageRef }, { type: 'image', attachment: secondRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -969,7 +992,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: secondRef }, { type: 'image', attachment: thirdRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -1019,7 +1042,7 @@ describe('DeepSeekAdapter against a mock server', () => { { type: 'image', attachment: imageRef }, { type: 'image', attachment: secondRef }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) @@ -1046,7 +1069,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ code: 'INVALID_REQUEST', message: 'file_id file-api-1 expired' }) expect(server.requests).toHaveLength(2) @@ -1072,7 +1095,7 @@ describe('DeepSeekAdapter against a mock server', () => { model, messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) expect(resolveApiKey).not.toHaveBeenCalled() @@ -1100,7 +1123,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: imageRef }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }))).rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) expect(resolveApiKey).not.toHaveBeenCalled() @@ -1117,7 +1140,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })) { kinds.push(chunk.type) @@ -1133,7 +1156,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], sessionId: SessionId('child-session'), }) @@ -1150,7 +1173,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], purpose: 'compaction', }) @@ -1170,7 +1193,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) await assemble(ctx,{ @@ -1178,7 +1201,7 @@ describe('DeepSeekAdapter against a mock server', () => { reasoningEffort: ReasoningEffortId('off'), messages: [createUserMessage({ content: [{ type: 'text', text: 'hi again' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) await assemble(ctx,{ @@ -1186,7 +1209,7 @@ describe('DeepSeekAdapter against a mock server', () => { reasoningEffort: ReasoningEffortId('max'), messages: [createUserMessage({ content: [{ type: 'text', text: 'one more time' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) expect(server.requests[0]).toMatchObject({ @@ -1225,7 +1248,7 @@ describe('DeepSeekAdapter against a mock server', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) expect(server.requests[0]).toMatchObject({ @@ -1254,7 +1277,7 @@ describe('DeepSeekAdapter against a mock server', () => { reasoningEffort: ReasoningEffortId('high'), messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) expect(result.finish).toMatchObject({ @@ -1276,7 +1299,7 @@ describe('DeepSeekAdapter against a mock server', () => { reasoningEffort: ReasoningEffortId(effort), messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) await expect(async () => { diff --git a/packages/llm/llm-deepseek/tests/assemble.ts b/packages/llm/llm-deepseek/tests/assemble.ts index 2ed51d0f3d..20770fca7d 100644 --- a/packages/llm/llm-deepseek/tests/assemble.ts +++ b/packages/llm/llm-deepseek/tests/assemble.ts @@ -7,10 +7,10 @@ import { BlockAssembler } from '@deepseek-ai/dsh-llm' import type { Context } from '@deepseek-ai/cordis' -import type { FinishReason, GenerateOptions, Message, TokenUsage } from '@deepseek-ai/dsh-llm' +import type { AssistantMessage, FinishReason, GenerateOptions, TokenUsage } from '@deepseek-ai/dsh-llm' export interface AssembledResult { - message: Message + message: AssistantMessage usage?: TokenUsage finish: FinishReason } @@ -21,7 +21,6 @@ export async function assemble(ctx: Context, options: Omit { { type: 'image', attachment: IMAGE_REF }, { type: 'image', attachment: IMAGE_REF }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })] await assemble(ctx, { model: 'deepseek-flash', messages }) @@ -232,7 +239,7 @@ describe('request-level dynamic configuration', () => { { type: 'image', attachment: IMAGE_REF, offloaded: true }, { type: 'image', attachment: IMAGE_REF }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], }) diff --git a/packages/llm/llm-deepseek/tests/messages/adapter.e2e.ts b/packages/llm/llm-deepseek/tests/messages/adapter.e2e.ts index fd085e373c..aeb6ebe3e8 100644 --- a/packages/llm/llm-deepseek/tests/messages/adapter.e2e.ts +++ b/packages/llm/llm-deepseek/tests/messages/adapter.e2e.ts @@ -50,7 +50,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('DeepSeek Messages real API', () const model = IN_HISTORY_MODEL as string // Each case owns the capability, even for a model with an in-history catalog default. const ctx = await boot([{ id: model, ...inHistory ? { systemPromptUpdate: 'in-history' as const } : {} }]) - const history: Message[] = [createSystemMessage('Reply to every user message with exactly PROMPT_FIRST.', 'test'), user('Answer now.')] + const history: Message[] = [createSystemMessage('Reply to every user message with exactly PROMPT_FIRST.'), user('Answer now.')] const reply = async (expected: string) => { const saved = JSON.stringify(history) const response = await assemble(ctx.llm.stream(options({ model, messages: history, reasoningEffort: ReasoningEffortId('high') })), model) @@ -60,10 +60,10 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('DeepSeek Messages real API', () history.push(response.message) } await reply('PROMPT_FIRST') - history.push(createSystemMessage('Reply to every user message with exactly PROMPT_SECOND.', 'test'), user('Answer again.')) + history.push(createSystemMessage('Reply to every user message with exactly PROMPT_SECOND.'), user('Answer again.')) await reply('PROMPT_SECOND') const withoutSystem = history.filter(message => message.role !== 'system') - history.splice(0, history.length, createSystemMessage('', 'test'), ...withoutSystem, user('Reply with exactly PROMPT_CLEARED.')) + history.splice(0, history.length, createSystemMessage(''), ...withoutSystem, user('Reply with exactly PROMPT_CLEARED.')) await reply('PROMPT_CLEARED') }) diff --git a/packages/llm/llm-deepseek/tests/messages/adapter.spec.ts b/packages/llm/llm-deepseek/tests/messages/adapter.spec.ts index d6752df872..6a9fa25af6 100644 --- a/packages/llm/llm-deepseek/tests/messages/adapter.spec.ts +++ b/packages/llm/llm-deepseek/tests/messages/adapter.spec.ts @@ -15,8 +15,8 @@ import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { AttachmentId } from '@deepseek-ai/dsh-attachment' import Loader from '@deepseek-ai/cordis-plugin-loader' import Include from '@deepseek-ai/cordis-plugin-include' -import LlmRuntime, { createAssistantMessage, createSystemMessage, createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' -import type { Message } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createAssistantMessage, createSystemMessage, createToolResultMessage, createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, Message } from '@deepseek-ai/dsh-llm' import { credentialRef } from '@deepseek-ai/dsh-credentials' import LocalCredentials from '@deepseek-ai/dsh-credentials-local' import FileSettings from '@deepseek-ai/dsh-settings-file' @@ -52,10 +52,16 @@ async function send(agent: Agent, text: string) { expect(agent.session.snapshotEvents().at(-1)).toMatchObject({ type: 'turn/end', data: { reason: { kind: 'completed' } } }) } +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'saved-notice': { kind: 'saved-notice' } + } +} + describe('direct Messages HTTP', () => { it('continues through Messages with assistant blocks in saved user history', async () => { const http = await endpoint() - const notice = createUserMessage({ source: { kind: 'plugin', plugin: 'saved-notice' }, content: [ + const notice = createUserMessage({ source: { kind: 'saved-notice' }, content: [ { type: 'text', text: 'Background subagent finished.' }, { type: 'reasoning', text: 'child reasoning' }, { type: 'tool-call', id: ToolCallId('child-call'), name: 'read', arguments: '{}' }, @@ -353,9 +359,9 @@ describe('Cordis provider composition', () => { it('maps multiple system snapshots on direct compaction calls to the latest prompt', async () => { const { ctx, http } = await boot() - const history = [createSystemMessage('old', 'test'), user(), + const history = [createSystemMessage('old'), user(), createAssistantMessage({ content: [{ type: 'text', text: 'OK' }], source: { provider: 'deepseek-official', model: MODEL } }), - createSystemMessage('current', 'test'), user('summarize')] + createSystemMessage('current'), user('summarize')] const saved = JSON.stringify(history) const response = await assemble(ctx.llm.stream(options({ messages: history, purpose: 'compaction' }))) expect(response.assembler.finish.kind).toBe('stop') @@ -372,7 +378,19 @@ describe('Cordis provider composition', () => { const records = fixture.trim().split('\n').map(line => JSON.parse(line) as { type: string; data: { message?: Message } }) const assistant = records.find(record => record.type === 'assistant/message')!.data.message! if (assistant.source.kind === 'model') assistant.source.provider = 'deepseek-official' - const result = records.find(record => record.type === 'tool/result')!.data.message! + // The released v2 row still wraps its tool result inside a user message. + const released = records.find(record => record.type === 'tool/result')!.data.message! as unknown as { + readonly content: readonly { + readonly type: string + readonly toolCallId: ToolCallId + readonly content: readonly ContentBlock[] + readonly isError?: boolean + }[] + } + const releasedBlock = released.content[0]! + const result = createToolResultMessage({ + callId: releasedBlock.toolCallId, content: [...releasedBlock.content], isError: releasedBlock.isError === true, + }) const saved = JSON.stringify([assistant, result]) const response = await assemble(ctx.llm.stream(options({ messages: [user(), assistant, result] }))) expect(response.assembler.finish.kind).toBe('stop') diff --git a/packages/llm/llm-deepseek/tests/messages/files.spec.ts b/packages/llm/llm-deepseek/tests/messages/files.spec.ts index 1b5ee31941..e4f1a9060e 100644 --- a/packages/llm/llm-deepseek/tests/messages/files.spec.ts +++ b/packages/llm/llm-deepseek/tests/messages/files.spec.ts @@ -174,11 +174,11 @@ describe('Messages Files requests', () => { const prepared = await prepareImages(messages, resolveAdapterOptions({}), 'text-model', undefined, () => ({ readonlyPath: '/workspace/image.png' }), new AbortController().signal) expect(prepared.versions.size).toBe(0) - expect(prepared.messages[0]?.content).toMatchObject([{ type: 'tool-result', content: [ + expect(prepared.messages[0]?.content).toMatchObject([ { type: 'text', text: expect.stringContaining('image omitted to fit request image limits') as string }, - ] }]) + ]) expect(JSON.stringify(prepared.messages)).toContain('/workspace/image.png') - expect(messages[0]?.content).toMatchObject([{ type: 'tool-result', content: [{ type: 'image', offloaded: true }] }]) + expect(messages[0]?.content).toMatchObject([{ type: 'image', offloaded: true }]) }) it('falls back when the Files deadline expires but never converts caller cancellation into another request', async () => { diff --git a/packages/llm/llm-deepseek/tests/messages/fixtures/input-history.ts b/packages/llm/llm-deepseek/tests/messages/fixtures/input-history.ts index dbfbad61bf..ce98439370 100644 --- a/packages/llm/llm-deepseek/tests/messages/fixtures/input-history.ts +++ b/packages/llm/llm-deepseek/tests/messages/fixtures/input-history.ts @@ -6,6 +6,12 @@ import { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' import { resolveAdapterOptions } from '../../../src/config.ts' import { serialize } from '../../../src/protocols/messages/serialize.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'plugin:messages-input-history-snapshot': { kind: 'plugin:messages-input-history-snapshot' } + } +} + export const name = 'messages-input-history-snapshot' export const inject = ['llm'] @@ -14,7 +20,7 @@ export function apply(ctx: Context): void { ctx.on('agent/pre-step', async (_input, next) => { const decision = await next() if (decision.kind !== 'enter') return decision - const source = { kind: 'plugin' as const, plugin: name } + const source = { kind: `plugin:${name}` } as const return { ...decision, messages: [ ...decision.messages, createUserMessage({ source, content: [ diff --git a/packages/llm/llm-deepseek/tests/messages/serialize.spec.ts b/packages/llm/llm-deepseek/tests/messages/serialize.spec.ts index eb1c6bccdf..dbb1424056 100644 --- a/packages/llm/llm-deepseek/tests/messages/serialize.spec.ts +++ b/packages/llm/llm-deepseek/tests/messages/serialize.spec.ts @@ -1,7 +1,7 @@ /** Request conversion and durable replay validation. */ import { describe, expect, it, vi } from 'vitest' -import { createAssistantMessage, createMessage, createSystemMessage, createToolResultMessage, ReasoningEffortId, ToolCallId } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, GenerateOptions, ImageBlock, Message } from '@deepseek-ai/dsh-llm' +import { createDeveloperMessage, createUserMessage, createAssistantMessage, createMessage, createSystemMessage, createToolResultMessage, ReasoningEffortId, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, GenerateOptions, ImageBlock, Message, RequestMessage, RequestUserInput } from '@deepseek-ai/dsh-llm' import { AttachmentId, ImageVariantId } from '@deepseek-ai/dsh-attachment' import type { AttachmentStore, ImageAttachmentRef, RequestImageAttachment } from '@deepseek-ai/dsh-attachment' import { resolveAdapterOptions } from '../../src/config.ts' @@ -16,17 +16,69 @@ const connection = resolveAdapterOptions({}) const call = (id = 'a'): ContentBlock => ({ type: 'tool-call', id: ToolCallId(id), name: 'read', arguments: '{"path":"a"}' }) const assistant = (content: ContentBlock[]) => createAssistantMessage({ content, source: { provider: 'deepseek-official', model: MODEL } }) const result = (id = 'a', content: ContentBlock[] = [{ type: 'text', text: 'result' }]) => createToolResultMessage({ callId: ToolCallId(id), content, isError: false }) -const body = (messages: Message[] = [user()], overrides: Partial = {}) => serialize( +const body = (messages: RequestMessage[] = [user()], overrides: Partial = {}) => serialize( options({ messages, ...overrides }), connection, messages, new Map(), () => undefined, ) const capable = resolveAdapterOptions({ models: [{ id: MODEL, systemPromptUpdate: 'in-history' }] }) const nativeBody = (messages: Message[]) => serialize(options({ messages }), capable, messages, new Map(), () => undefined) describe('Messages request conversion', () => { + it('rejects unknown plugin content without interpreting its payload', () => { + expect(() => body([createUserMessage({ source: { kind: 'user' }, content: [ + { type: 'plugin:text', text: 'opaque' } as never, + ] })])).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + }) + it.each(['user', 'system', 'assistant', 'tool'] as const)('rejects tool-change blocks in %s history', (role) => { + for (const type of ['tool-addition', 'tool-removal'] as const) { + const message = { id: 'invalid', role, source: { kind: 'test' }, content: [{ type, toolName: 'search' }] } as unknown as Message + expect(() => body([message])).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + } + }) + + it('rejects deferred tool definitions until provider loading is implemented', () => { + expect(() => body([], { tools: [{ name: 'search', description: '', parameters: {}, deferLoading: true }] })) + .toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + }) + + it('preserves the exact request with request-only text after durable tool results', () => { + const prefix = [user(), assistant([call()]), result()] + const input: RequestUserInput = { role: 'user', content: [{ type: 'text', text: 'review or summarize this input' }] } + const durable = createUserMessage({ content: input.content, source: { kind: 'user' } }) + expect(body([...prefix, input], { system: 'policy' })).toEqual(body([...prefix, durable], { system: 'policy' })) + }) + + it('preserves request-only image content through image preparation and wire conversion', async () => { + const attachment: ImageAttachmentRef = { + attachmentId: AttachmentId(`sha256:${'e'.repeat(64)}`), mediaType: 'image/png', bytes: 3, width: 1, height: 1, + } + const version: RequestImageAttachment = { + variantId: ImageVariantId(`sha256:${'f'.repeat(64)}`), attachment, data: Uint8Array.of(1, 2, 3), + mediaType: 'image/png', bytes: 3, width: 1, height: 1, depth: 'uchar', space: 'srgb', hasAlpha: true, + } + const input: RequestUserInput = { role: 'user', content: [ + { type: 'text', text: 'before' }, { type: 'image', attachment }, { type: 'text', text: 'after' }, + ] } + const store = { readImageRequest: async () => version } as unknown as AttachmentStore + const vision = resolveAdapterOptions({ models: [{ id: MODEL, inputModalities: ['text', 'image'] }] }) + const durable = createUserMessage({ content: input.content, source: { kind: 'user' } }) + const actual = await prepareImages([input], vision, MODEL, store, () => undefined, new AbortController().signal) + const expected = await prepareImages([durable], vision, MODEL, store, () => undefined, new AbortController().signal) + expect(serialize(options({ messages: [input] }), vision, actual.messages, actual.versions, () => undefined)) + .toEqual(serialize(options({ messages: [durable] }), vision, expected.messages, expected.versions, () => undefined)) + expect(actual.messages[0]).toBe(input) + expect(input).not.toHaveProperty('id') + expect(input).not.toHaveProperty('source') + }) + + it('rejects developer history while provider serialization is unsupported', () => { + const message = createDeveloperMessage({ content: [{ type: 'tool-addition', toolName: 'search' }], source: { kind: 'tool-registry' } }) + expect(() => body([message])).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + }) + it('keeps the original top-level prompt and cached prefix while appending native system updates', () => { - const head = createSystemMessage('original', 'test') + const head = createSystemMessage('original') const first = [head, user('first')] - const update = createSystemMessage('updated', 'test') + const update = createSystemMessage('updated') const second = [...first, assistant([{ type: 'text', text: 'one' }]), update, user('second')] const saved = JSON.stringify(second) const before = nativeBody(first) @@ -43,8 +95,8 @@ describe('Messages request conversion', () => { }) it('places system updates after all parallel tool results and before the next assistant', () => { - const history = [createSystemMessage('original', 'test'), user(), assistant([call(), call('b')]), - createSystemMessage('first update', 'test'), result(), createSystemMessage('second update', 'test'), result('b'), + const history = [createSystemMessage('original'), user(), assistant([call(), call('b')]), + createSystemMessage('first update'), result(), createSystemMessage('second update'), result('b'), user('more input'), assistant([{ type: 'text', text: 'done' }])] const request = nativeBody(history) expect(request.messages.map(message => message.role)).toEqual(['user', 'assistant', 'user', 'system', 'system', 'assistant']) @@ -55,20 +107,20 @@ describe('Messages request conversion', () => { }) it('accepts native trailing updates without a top-level prompt and rejects unrepresentable positions', () => { - const update = createSystemMessage('update', 'test') + const update = createSystemMessage('update') expect(nativeBody([user(), update])).toMatchObject({ messages: [ { role: 'user' }, { role: 'system', content: [{ type: 'text', text: 'update' }] }, ] }) expect(nativeBody([user(), update]).system).toBeUndefined() expect(() => nativeBody([user(), assistant([{ type: 'text', text: 'done' }]), update])).toThrow(/preceding user/) - expect(() => nativeBody([user(), createSystemMessage('', 'test')])).toThrow(/empty in-history/) + expect(() => nativeBody([user(), createSystemMessage('')])).toThrow(/empty in-history/) expect(() => nativeBody([user(), assistant([call(), call('b')]), update, result()])).toThrow(/immediate results/) }) it.each([[], [{ type: 'reasoning', text: 'child reasoning' }], [call('child-call')]] satisfies ContentBlock[][])( 'rejects native system updates when their user input is omitted %#', (...content) => { const empty = createMessage({ role: 'user', source: { kind: 'user' }, content }) - const history = [user(), assistant([{ type: 'text', text: 'answer' }]), createSystemMessage('updated', 'test'), empty] + const history = [user(), assistant([{ type: 'text', text: 'answer' }]), createSystemMessage('updated'), empty] const saved = JSON.stringify(history) for (const messages of [history, [...history, assistant([{ type: 'text', text: 'next answer' }])]]) { expect(() => nativeBody(messages)).toThrow(expect.objectContaining({ @@ -83,7 +135,7 @@ describe('Messages request conversion', () => { it('keeps native system updates after retained text or tool results beside omitted user input', () => { const reasoning: ContentBlock = { type: 'reasoning', text: 'child reasoning' } const empty = createMessage({ role: 'user', source: { kind: 'user' }, content: [reasoning] }) - const update = createSystemMessage('updated', 'test') + const update = createSystemMessage('updated') for (const [previous, retained, expected] of [ [assistant([{ type: 'text', text: 'answer' }]), user('continue'), [{ type: 'text', text: 'continue' }]], [assistant([call()]), result('a', [reasoning]), [{ type: 'tool_result', tool_use_id: 'a', content: [], is_error: false }]], @@ -115,7 +167,7 @@ describe('Messages request conversion', () => { it('preserves empty results without inventing model-visible output', () => { const response = body([user(), assistant([call()]), result('a', [])]) expect(response.messages[2]?.content[0]).toMatchObject({ content: [] }) - const minimal = createMessage({ role: 'user', source: { kind: 'user' }, content: [{ type: 'tool-result', toolCallId: ToolCallId('a'), content: [{ type: 'text', text: '' }] }] }) + const { isError: _isError, ...minimal } = createToolResultMessage({ callId: ToolCallId('a'), content: [{ type: 'text', text: '' }], isError: false }) expect(body([assistant([call()]), minimal]).messages[1]?.content[0]).toEqual({ type: 'tool_result', tool_use_id: 'a', content: [] }) }) @@ -167,7 +219,7 @@ describe('Messages request conversion', () => { }) it('collects leading system text and maps tools, stop sequences and explicit output cap', () => { - const system = createMessage({ role: 'system', source: { kind: 'plugin', plugin: 'test' }, content: [{ type: 'text', text: 'instructions' }] }) + const system = createMessage({ role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'text', text: 'instructions' }] }) expect(body([system, user()], { system: 'top', maxTokens: 123, stop: ['END'], tools: [{ name: 'read', description: 'Read a file', parameters: { type: 'object' } }] })).toMatchObject({ system: 'top\n\ninstructions', max_tokens: 123, stop_sequences: ['END'], tools: [{ name: 'read', description: 'Read a file', input_schema: { type: 'object' } }], }) @@ -176,9 +228,9 @@ describe('Messages request conversion', () => { it('uses the latest complete system snapshot without changing tool history or durable messages', () => { const conversation = [user(), assistant([call()]), result(), assistant([{ type: 'text', text: 'done' }]), user('continue')] - const history = [createSystemMessage('obsolete', 'test'), ...conversation.slice(0, 2), - createSystemMessage('intermediate', 'test'), ...conversation.slice(2, 4), - createSystemMessage('current', 'test'), conversation[4]!] + const history = [createSystemMessage('obsolete'), ...conversation.slice(0, 2), + createSystemMessage('intermediate'), ...conversation.slice(2, 4), + createSystemMessage('current'), conversation[4]!] const saved = JSON.stringify(history) expect(body(history)).toEqual({ ...body(conversation), system: 'current' }) expect(body(history, { system: 'one-shot prefix' }).system).toBe('one-shot prefix\n\ncurrent') @@ -186,22 +238,22 @@ describe('Messages request conversion', () => { }) it('replaces adjacent system snapshots and joins blocks only within the current snapshot', () => { - const latest = createMessage({ role: 'system', source: { kind: 'plugin', plugin: 'test' }, + const latest = createMessage({ role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'text', text: 'part one' }, { type: 'text', text: ' and part two' }] }) - expect(body([createSystemMessage('old', 'test'), latest, user()]).system).toBe('part one and part two') + expect(body([createSystemMessage('old'), latest, user()]).system).toBe('part one and part two') }) it.each([[], [{ type: 'text' as const, text: '' }]].map(content => ({ content })))('clears earlier prompt snapshots with empty content %#', ({ content }) => { - const cleared = createMessage({ role: 'system', source: { kind: 'plugin', plugin: 'test' }, content }) - const history = [createSystemMessage('old', 'test'), user(), cleared] + const cleared = createMessage({ role: 'system', source: { kind: 'system-prompt' }, content }) + const history = [createSystemMessage('old'), user(), cleared] expect(body(history).system).toBeUndefined() expect(body(history, { system: 'one-shot prefix' }).system).toBe('one-shot prefix') expect(body(history, { system: '' }).system).toBeUndefined() }) it('rejects non-text system content even when a later snapshot supersedes it', () => { - const invalid = createMessage({ role: 'system', source: { kind: 'plugin', plugin: 'test' }, content: [{ type: 'reasoning', text: 'bad' }] }) - expect(() => body([invalid, user(), createSystemMessage('current', 'test')])).toThrow(/non-text system/) + const invalid = createMessage({ role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'reasoning', text: 'bad' }] }) + expect(() => body([invalid, user(), createSystemMessage('current')])).toThrow(/non-text system/) }) it.each(['off', 'low', 'high', 'max'])('maps reasoning effort %s', (effort) => { @@ -370,14 +422,14 @@ describe('Messages images', () => { }) const history = [result('a', [image, image])] const prepared = await prepareImages(history, config, model, attachments, access, signal) - expect(prepared.messages[0]?.content[0]).toMatchObject({ content: [image, image] }) + expect(prepared.messages[0]?.content).toMatchObject([image, image]) expect(() => inlineImages(prepared.messages, prepared.versions, config)).toThrow(expect.objectContaining({ failure: expect.objectContaining({ code: 'IMAGE_OFFLOAD_REQUIRED', offloadImages: 1 }) as unknown, })) const offloaded: ImageBlock = { ...image, offloaded: true } const retry = await prepareImages([result('a', [offloaded, image])], config, model, attachments, access, signal) - expect(inlineImages(retry.messages, retry.versions, config)[0]?.content[0]).toMatchObject({ content: [{ type: 'text' }, { type: 'image' }] }) - expect(history[0]?.content[0]).toMatchObject({ content: [image, image] }) + expect(inlineImages(retry.messages, retry.versions, config)[0]?.content).toMatchObject([{ type: 'text' }, { type: 'image' }]) + expect(history[0]?.content).toMatchObject([image, image]) expect(imagePricing(config, model, access).priceImages([image, image]).map(entry => entry.visualTokens)) .toEqual([expect.any(Number), expect.any(Number)]) const large = { readImageRequest: async () => ({ ...version, bytes: 30, data: new Uint8Array(30) }) } as unknown as AttachmentStore @@ -393,6 +445,7 @@ describe('Messages images', () => { await expect(prepareImages([assistant([image])], connection, model, attachments, access, signal)).rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) expect(() => body([result('a', [image])])).toThrow(/image/) expect(() => body([assistant([image])])).toThrow(/assistant/) + // @ts-expect-error -- malformed provider input can carry a retired nested result block. expect(() => body([result('a', [{ type: 'tool-result', toolCallId: ToolCallId('nested'), content: [] }])])) .toThrow(/user\/tool-result content tool-result/) expect(() => serialize(options({ model }), connection, [result('a', [image])], new Map([[ref.attachmentId, version]]), access, undefined, new Map())) diff --git a/packages/llm/llm-deepseek/tests/serialize.spec.ts b/packages/llm/llm-deepseek/tests/serialize.spec.ts index 25cbbbbb49..804536fe3b 100644 --- a/packages/llm/llm-deepseek/tests/serialize.spec.ts +++ b/packages/llm/llm-deepseek/tests/serialize.spec.ts @@ -1,8 +1,9 @@ import { describe, expect, it, vi } from 'vitest' import { AttachmentId, ImageVariantId } from '@deepseek-ai/dsh-attachment' import type { ImageAttachmentRef, ImageMediaType, RequestImageAttachment } from '@deepseek-ai/dsh-attachment' -import { createUserMessage, ToolCallId, ReasoningEffortId, createMessage } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, GenerateOptions, Message } from '@deepseek-ai/dsh-llm' +import { createDeveloperMessage, createToolResultMessage, createUserMessage, ToolCallId, ReasoningEffortId, createMessage } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, GenerateOptions, Message, RequestUserInput } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { serializeMessages, serializeMessagesWithImages, @@ -11,6 +12,12 @@ import { } from '../src/protocols/chat-completions/serialize.ts' import type { ImageSerializationOptions } from '../src/protocols/chat-completions/serialize.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + type FileResolver = Extract['resolveFileId'] function request(overrides: Partial = {}): GenerateOptions { @@ -78,12 +85,51 @@ function inlineImageOptions( } } +it.each(['user', 'system', 'assistant', 'tool'] as const)('rejects tool-change blocks in %s history', (role) => { + for (const type of ['tool-addition', 'tool-removal'] as const) { + const message = { id: 'invalid', role, source: { kind: 'test' }, content: [{ type, toolName: 'search' }] } as unknown as Message + expect(() => serializeMessages([message])).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + } +}) + +it('rejects deferred tool definitions until provider loading is implemented', () => { + expect(() => serializeRequest(request({ tools: [{ name: 'search', description: '', parameters: {}, deferLoading: true }] }))) + .toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) +}) + +describe('request-only user input', () => { + it('preserves the exact text request and durable tool-result prefix', () => { + const prefix = [ + createMessage({ role: 'assistant', content: [{ type: 'tool-call', id: ToolCallId('lookup'), name: 'lookup', arguments: '{}' }], + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' } }), + createToolResultMessage({ callId: ToolCallId('lookup'), content: [{ type: 'text', text: 'result' }], isError: false }), + ] + const input: RequestUserInput = { role: 'user', content: [{ type: 'text', text: 'review or summarize this input' }] } + const durable = createUserMessage({ content: input.content, source: { kind: 'test' } }) + expect(serializeRequest(request({ messages: [...prefix, input], system: 'policy' }))) + .toEqual(serializeRequest(request({ messages: [...prefix, durable], system: 'policy' }))) + }) + + it('preserves image ordering and bytes without manufacturing durable metadata', async () => { + const ref = imageRef() + const input: RequestUserInput = { role: 'user', content: [ + { type: 'text', text: 'before' }, { type: 'image', attachment: ref }, { type: 'text', text: 'after' }, + ] } + const durable = createUserMessage({ content: input.content, source: { kind: 'test' } }) + const actual = await serializeRequestWithImages(request({ messages: [input] }), inlineImageOptions([ref])) + const expected = await serializeRequestWithImages(request({ messages: [durable] }), inlineImageOptions([ref])) + expect(actual).toEqual(expected) + expect(input).not.toHaveProperty('id') + expect(input).not.toHaveProperty('source') + }) +}) + describe('serializeMessages', () => { it('maps user text to string content', () => { const wire = serializeMessages([ createUserMessage({ content: [{ type: 'text', text: 'hello ' }, { type: 'text', text: 'world' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), ]) expect(wire).toEqual([{ role: 'user', content: 'hello world' }]) @@ -93,7 +139,7 @@ describe('serializeMessages', () => { const wire = serializeMessages([ createMessage({ role: 'system', content: [{ type: 'text', text: 'be brief' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'system-prompt' }, }), ]) expect(wire).toEqual([{ role: 'system', content: 'be brief' }]) @@ -107,7 +153,7 @@ describe('serializeMessages', () => { { type: 'reasoning', text: 'thinking…' }, { type: 'text', text: 'answer' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), ]) // A gateway that re-encodes the conversation for another vendor recovers @@ -124,7 +170,7 @@ describe('serializeMessages', () => { { type: 'reasoning', text: 'I should check the weather.' }, { type: 'tool-call', id: ToolCallId('call-1'), name: 'get_weather', arguments: '{"city":"Paris"}' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), ]) expect(wire).toEqual([{ @@ -145,45 +191,41 @@ describe('serializeMessages', () => { { type: 'tool-call', id: ToolCallId('a'), name: 'one', arguments: '{}' }, { type: 'tool-call', id: ToolCallId('b'), name: 'two', arguments: '{}' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), ]) const assistant = wire[0] as { tool_calls: { id: string }[] } expect(assistant.tool_calls.map(call => call.id)).toEqual(['a', 'b']) }) - it('turns tool results into role:tool messages', () => { + it('turns tool messages into role:tool wire messages', () => { const wire = serializeMessages([ - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('call-1'), - content: [{ type: 'text', text: 'Sunny 22C' }], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId('call-1'), + content: [{ type: 'text', text: 'Sunny 22C' }], + isError: false, }), ]) expect(wire).toEqual([{ role: 'tool', tool_call_id: 'call-1', content: 'Sunny 22C' }]) }) - it('sends a sentinel for empty tool-result content', () => { + it('sends a sentinel for empty tool content', () => { const wire = serializeMessages([ - createUserMessage({ - content: [{ type: 'tool-result', toolCallId: ToolCallId('call-1'), content: [] }], - source: { kind: 'plugin', plugin: 'test' }, - }), + createToolResultMessage({ callId: ToolCallId('call-1'), content: [], isError: false }), ]) expect(wire).toEqual([{ role: 'tool', tool_call_id: 'call-1', content: '(no output)' }]) }) - it('splits mixed user text + tool results into separate wire messages', () => { + it('keeps user text and tool messages as separate wire messages', () => { const wire = serializeMessages([ createUserMessage({ - content: [ - { type: 'text', text: 'context note' }, - { type: 'tool-result', toolCallId: ToolCallId('call-1'), content: [{ type: 'text', text: 'ok' }] }, - ], - source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'context note' }], + source: { kind: 'test' }, + }), + createToolResultMessage({ + callId: ToolCallId('call-1'), + content: [{ type: 'text', text: 'ok' }], + isError: false, }), ]) expect(wire).toEqual([ @@ -199,7 +241,7 @@ describe('serializeMessages', () => { { type: 'chart', data: 'x' } as unknown as ContentBlock, { type: 'text', text: 'see chart' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), ]) expect(wire).toEqual([{ role: 'user', content: 'see chart' }]) @@ -214,14 +256,14 @@ describe('serializeMessages', () => { mediaType: 'image/png', bytes: 68, width: 1, height: 1, }, }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })])).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) }) it('emits an empty user message rather than dropping block-less messages', () => { const wire = serializeMessages([createUserMessage({ content: [], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })]) expect(wire).toEqual([{ role: 'user', content: '' }]) }) @@ -230,7 +272,7 @@ describe('serializeMessages', () => { describe('serializeRequest', () => { const history: Message[] = [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })] it('always streams with usage and maps the basics', () => { @@ -253,7 +295,7 @@ describe('serializeRequest', () => { const systemMessage = createMessage({ role: 'system', content: [{ type: 'text', text: 'be helpful' }], - source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, + source: { kind: 'system-prompt' }, }) const tools = [{ name: 'f', description: 'F', parameters: { type: 'object', properties: {} } }] const fromHistory = serializeRequest(request({ messages: [systemMessage, ...history], tools })) @@ -376,7 +418,7 @@ describe('image serialization', () => { { type: 'image', attachment: ref }, { type: 'text', text: 'after' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), imageOptions([ref], resolveFileId)) @@ -402,7 +444,7 @@ describe('image serialization', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), inlineImageOptions([ref])) @@ -421,7 +463,7 @@ describe('image serialization', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), imageOptions([ref])) @@ -448,7 +490,7 @@ describe('image serialization', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), images) @@ -467,30 +509,24 @@ describe('image serialization', () => { const ref = imageRef() await expect(serializeMessagesWithImages([createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], imageOptions([]))).rejects.toMatchObject({ code: 'INVALID_REQUEST' }) }) it('keeps tool content textual and groups consecutive tool-result images afterward', async () => { const messages = [ - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('first'), - content: [{ type: 'image', attachment: imageRef() }], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId('first'), + content: [{ type: 'image', attachment: imageRef() }], + isError: false, }), - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('second'), - content: [ - { type: 'text', text: 'caption' }, - { type: 'image', attachment: imageRef('image/jpeg') }, - ], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId('second'), + content: [ + { type: 'text', text: 'caption' }, + { type: 'image', attachment: imageRef('image/jpeg') }, + ], + isError: false, }), ] @@ -521,41 +557,37 @@ describe('image serialization', () => { ]) }) - it('does not emit an empty user message for ignored content beside a tool result', async () => { - const messages = [createUserMessage({ - content: [ - { type: 'text', text: '' }, - { type: 'chart', data: 'ignored' } as unknown as ContentBlock, - { - type: 'tool-result', - toolCallId: ToolCallId('result'), - content: [{ type: 'text', text: 'ok' }], - }, - ], - source: { kind: 'plugin', plugin: 'test' }, - })] + it('keeps an empty user message for ignored content beside a tool message', async () => { + const messages = [ + createUserMessage({ + content: [ + { type: 'text', text: '' }, + { type: 'chart', data: 'ignored' } as unknown as ContentBlock, + ], + source: { kind: 'test' }, + }), + createToolResultMessage({ + callId: ToolCallId('result'), + content: [{ type: 'text', text: 'ok' }], + isError: false, + }), + ] await expect(serializeMessagesWithImages(messages, imageOptions([], fileResolver()))).resolves.toEqual([ + { role: 'user', content: '' }, { role: 'tool', tool_call_id: 'result', content: 'ok' }, ]) }) - it('recursively converts nested tool-result content and preserves the empty fallback', async () => { - const messages = [createUserMessage({ - content: [ - { - type: 'tool-result', - toolCallId: ToolCallId('nested'), - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('inner'), - content: [{ type: 'text', text: 'inside' }], - }], - }, - { type: 'tool-result', toolCallId: ToolCallId('empty'), content: [] }, - ], - source: { kind: 'plugin', plugin: 'test' }, - })] + it('converts consecutive tool messages and preserves the empty fallback', async () => { + const messages = [ + createToolResultMessage({ + callId: ToolCallId('nested'), + content: [{ type: 'text', text: 'inside' }], + isError: false, + }), + createToolResultMessage({ callId: ToolCallId('empty'), content: [], isError: false }), + ] await expect(serializeMessagesWithImages(messages, imageOptions([], fileResolver()))).resolves.toEqual([ { role: 'tool', tool_call_id: 'nested', content: 'inside' }, @@ -564,26 +596,23 @@ describe('image serialization', () => { }) it('flushes tool-result images before system and assistant history', async () => { - const imageResult = (id: string) => createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId(id), - content: [{ type: 'image', attachment: imageRef() }], - }], - source: { kind: 'plugin' as const, plugin: 'test' }, + const imageResult = (id: string) => createToolResultMessage({ + callId: ToolCallId(id), + content: [{ type: 'image', attachment: imageRef() }], + isError: false, }) const messages = [ imageResult('before-system'), createMessage({ role: 'system', content: [{ type: 'text', text: 'system history' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'system-prompt' }, }), imageResult('before-assistant'), createMessage({ role: 'assistant', content: [{ type: 'text', text: 'assistant history' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, }), ] @@ -621,7 +650,7 @@ describe('image serialization', () => { { type: 'image', attachment: png, offloaded: true }, { type: 'image', attachment: jpeg }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), images) @@ -647,7 +676,7 @@ describe('image serialization', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: Array.from({ length: 21 }, () => ({ type: 'image' as const, attachment: ref })), - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), inlineImageOptions([ref], 80, 40))).rejects.toMatchObject({ code: 'IMAGE_OFFLOAD_REQUIRED', @@ -655,6 +684,19 @@ describe('image serialization', () => { }) }) + it('uses the configured image-count quantum before resolving files', async () => { + const ref = imageRef() + const resolveFileId = fileResolver() + const messages = [createUserMessage({ + content: Array.from({ length: 3 }, () => ({ type: 'image' as const, attachment: ref })), + source: { kind: 'test' }, + })] + await expect(serializeRequestWithImages(request({ messages }), { + ...imageOptions([ref], resolveFileId), maxImagesPerRequest: 2, countQuantum: 2, + })).rejects.toMatchObject({ code: 'IMAGE_OFFLOAD_REQUIRED', failure: { offloadImages: 2 } }) + expect(resolveFileId).not.toHaveBeenCalled() + }) + it('counts only retained occurrences against the bound', async () => { const ref = imageRef('image/png', 3) const wire = await serializeRequestWithImages(request({ @@ -664,7 +706,7 @@ describe('image serialization', () => { ...Array.from({ length: 11 }, () => ({ type: 'image' as const, attachment: ref, offloaded: true as const })), ...Array.from({ length: 10 }, () => ({ type: 'image' as const, attachment: ref })), ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], }), inlineImageOptions([ref], 80, 40)) const content = wire.messages[0]?.content @@ -677,29 +719,44 @@ describe('image serialization', () => { model: 'deepseek-v4-flash-vision-exp', messages: [createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), imageOptions([]))).rejects.toMatchObject({ code: 'INVALID_REQUEST' }) }) it.each(['system', 'assistant'] as const)('rejects an image in %s history before reading attachments', async (role) => { const resolveFileId = vi.fn() - await expect(serializeMessagesWithImages([createMessage({ - role, - content: [{ type: 'image', attachment: imageRef() }], - source: { kind: 'plugin', plugin: 'test' }, - })], imageOptions([imageRef()], resolveFileId))) + const content: ContentBlock[] = [{ type: 'image', attachment: imageRef() }] + const message = role === 'system' + ? createMessage({ role, content, source: { kind: 'system-prompt' } }) + : createMessage({ role, content, source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' } }) + await expect(serializeMessagesWithImages([message], imageOptions([imageRef()], resolveFileId))) .rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) expect(resolveFileId).not.toHaveBeenCalled() }) + it('rejects developer history on text and image paths before reading attachments', async () => { + const resolveFileId = fileResolver() + const message = createDeveloperMessage({ + content: [{ type: 'tool-addition', toolName: 'search' }], + source: { kind: 'test' }, + }) + const failure = { code: 'UNSUPPORTED_CONTENT', message: 'Developer messages are not supported yet' } + expect(() => serializeMessages([message])).toThrow(expect.objectContaining(failure)) + await expect(serializeMessagesWithImages([message], imageOptions([], resolveFileId))) + .rejects.toMatchObject(failure) + await expect(serializeRequestWithImages(request({ messages: [message] }), imageOptions([], resolveFileId))) + .rejects.toMatchObject(failure) + expect(resolveFileId).not.toHaveBeenCalled() + }) + it('rejects unsupported image history before request offloading can replace it', async () => { const resolveFileId = vi.fn() await expect(serializeRequestWithImages(request({ messages: [createMessage({ role: 'system', content: [{ type: 'image', attachment: imageRef('image/png', 300) }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'system-prompt' }, })], }), imageOptions([imageRef('image/png', 300)], resolveFileId, 1))) .rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) @@ -712,7 +769,7 @@ describe('image serialization', () => { system: 'system prompt', messages: [createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }), imageOptions([ref])) expect(wire.messages[0]).toEqual({ role: 'system', content: 'system prompt' }) @@ -724,7 +781,7 @@ describe('image serialization', () => { const resolveFileId = vi.fn(() => Promise.reject(failure)) await expect(serializeMessagesWithImages([createUserMessage({ content: [{ type: 'image', attachment: imageRef() }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], imageOptions([imageRef()], resolveFileId))) .rejects.toMatchObject({ code: 'ATTACHMENT_CORRUPT' }) }) @@ -734,7 +791,7 @@ describe('image serialization', () => { const resolveFileId = vi.fn(() => Promise.reject(failure)) await expect(serializeMessagesWithImages([createUserMessage({ content: [{ type: 'image', attachment: imageRef() }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], imageOptions([imageRef()], resolveFileId))).rejects.toBe(failure) }) }) @@ -746,7 +803,7 @@ describe('review fixes: assistant content shapes', () => { // message without tool_calls ("content or tool_calls must be set"). const wire = serializeMessages([createMessage({ role: 'assistant', content: [], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })]) expect(wire).toEqual([{ role: 'assistant', content: '' }]) }) @@ -757,7 +814,7 @@ describe('review fixes: assistant content shapes', () => { // the session log and bricked every later turn of that session. const wire = serializeMessages([createMessage({ role: 'assistant', content: [{ type: 'reasoning', text: '你好!有什么我可以帮你的吗?' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })]) expect(wire).toEqual([{ role: 'assistant', content: '', reasoning_content: '你好!有什么我可以帮你的吗?', @@ -768,7 +825,7 @@ describe('review fixes: assistant content shapes', () => { const wire = serializeMessages([createMessage({ role: 'assistant', content: [{ type: 'tool-call', id: ToolCallId('c'), name: 'f', arguments: '{}' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })]) expect(wire[0]).toMatchObject({ content: '' }) }) diff --git a/packages/llm/llm-deepseek/tests/translate.spec.ts b/packages/llm/llm-deepseek/tests/translate.spec.ts index e54ae71a0e..5e19f0c94f 100644 --- a/packages/llm/llm-deepseek/tests/translate.spec.ts +++ b/packages/llm/llm-deepseek/tests/translate.spec.ts @@ -48,7 +48,7 @@ describe('translate: text', () => { ))) { assembler.push(chunk) } - const result = { message: assembler.message(), finish: assembler.finish } + const result = { message: assembler.message({ provider: 'mock', model: 'mock' }), finish: assembler.finish } expect(result.message.content).toEqual([{ type: 'text', text: 'hi' }]) expect(result.finish).toEqual({ kind: 'stop' }) }) diff --git a/packages/llm/llm-pi-ai/README.i18n.yaml b/packages/llm/llm-pi-ai/README.i18n.yaml index a1d3124f89..175e1ab36e 100644 --- a/packages/llm/llm-pi-ai/README.i18n.yaml +++ b/packages/llm/llm-pi-ai/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/llm/llm-pi-ai/README.md -README.md: 89ae11fff20923309f3fc90e30de9f92977dcba2 -README.zh.md: 23d7ad170b5434b65b4d50e9a141e532694337dc +README.md: 4b3297ab96c2c691f9bbf849d8e49cb10a126a6a +README.zh.md: b33381468891fa81b199cca40f22a59183f5076a diff --git a/packages/llm/llm-pi-ai/README.md b/packages/llm/llm-pi-ai/README.md index 89ae11fff2..4b3297ab96 100644 --- a/packages/llm/llm-pi-ai/README.md +++ b/packages/llm/llm-pi-ai/README.md @@ -27,6 +27,8 @@ English | [中文](README.zh.md) Mount this plugin when a composition routes model requests through pi-ai's provider catalogs or through gateways that pi-ai's installed catalog does not describe. The `providers` dictionary is the whole configuration surface: each key is the provider route name a request selects with `GenerateOptions.provider`. +The adapter accepts the LLM service's [request-only user inputs](../llm/README.md#use-this-package) alongside durable history. User identity and attribution do not enter pi-ai content; assistant replay metadata and tool-call correlation remain attached to durable messages. + ### When to choose it Choose this adapter when the same composition serves several providers, when a route needs pi-ai's catalog defaults with a few fields corrected, or when a hand-declared gateway must be reached through its own endpoint and protocol. Choose `dsh-llm-deepseek` for the direct DeepSeek route when the deployment needs no other provider. Both adapters can be mounted together because their route names do not collide; registering a route another adapter already owns fails plugin loading. @@ -154,7 +156,7 @@ The plugin declares every installed catalog provider it can authenticate in the ### Replay and vocabulary -Successful assistant responses store a versioned, lossless-JSON replay state beside the provider and model that produced them — response-level facts plus one per-block entry per streamed block. At request time, `LlmRuntime` passes replay state only when the same adapter instance owns both routes; the adapter validates it and restores native response ids, provider signatures, and optional `providerThinkingLevel` effort metadata, keeping absent effort metadata absent. Replay validates the requested model identity against the assistant source and separately restores an Anthropic response model when the provider resolved an alias or fallback. An unusable state degrades to provider-neutral content instead of failing the request. pi-ai tool-call arguments are parsed objects, so the adapter parses input and re-stringifies output to the harness raw-JSON convention; pi-ai in-stream error events map to terminal `finish` chunks. +Successful assistant responses store a versioned, lossless-JSON replay state beside the provider and model that produced them — response-level facts plus one per-block entry per streamed block. At request time, `LlmRuntime` passes replay state only when the same adapter instance owns both routes; the adapter validates it and restores native response ids, provider signatures, and optional `providerThinkingLevel` effort metadata, keeping absent effort metadata absent. Replay validates the requested model identity against the assistant source and separately restores an Anthropic response model when the provider resolved an alias or fallback. Absent or unusable replay state degrades to provider-neutral content while preserving the assistant source’s required provider and model. pi-ai tool-call arguments are parsed objects, so the adapter parses input and re-stringifies output to the harness raw-JSON convention; pi-ai in-stream error events map to terminal `finish` chunks. diff --git a/packages/llm/llm-pi-ai/README.zh.md b/packages/llm/llm-pi-ai/README.zh.md index 23d7ad170b..b333814688 100644 --- a/packages/llm/llm-pi-ai/README.zh.md +++ b/packages/llm/llm-pi-ai/README.zh.md @@ -27,6 +27,8 @@ kind: "package-reference" 当组合需要通过 pi-ai 的提供方目录、或通过 pi-ai 已安装目录未描述的网关路由模型请求时挂载本插件。`providers` 字典就是整个配置面:每个键都是请求用 `GenerateOptions.provider` 选择的提供方路由名。 +适配器接受 LLM 服务的[仅供请求使用的 user 输入](../llm/README.zh.md#use-this-package),并可将其与持久历史混用。user 身份与来源不会进入 pi-ai 内容;assistant 回放元数据和工具调用关联仍由持久消息携带。 + ### 何时选择 当同一组合服务多个提供方、某条路由需要 pi-ai 目录默认值并修正少数字段、或必须通过自有端点与协议到达手工声明网关时,选择本适配器。当部署不需要其他提供方时,选择 `dsh-llm-deepseek` 直连 DeepSeek 路由。两个适配器可以同时挂载,因为它们的路由名不冲突;注册其他适配器已拥有的路由会导致插件加载失败。 @@ -154,7 +156,7 @@ Settings 写入会在合并组合层与用户层后严格校验每个新增或 ### 回放与词汇 -成功 assistant 响应会存储带版本的、无损 JSON 回放状态,与产生它们的提供方和模型放在一起——响应级事实加每个流式块一条逐块条目。请求时,`LlmRuntime` 仅当同一适配器实例拥有两条路由时才传递回放状态;适配器校验它并恢复原生响应 id、提供方签名与可选的 `providerThinkingLevel` effort 元数据,缺失的 effort 元数据仍保持缺失。回放会对照 assistant 来源校验请求模型身份,并在提供方解析别名或回退时单独恢复 Anthropic 响应模型。无法使用的状态会降级为提供方无关内容而不是让请求失败。pi-ai 工具调用参数是解析后的对象,因此适配器解析输入并重新字符串化输出,以符合 harness 原始 JSON 约定;pi-ai 流内错误事件映射为终止 `finish` 分片。 +成功 assistant 响应会存储带版本的、无损 JSON 回放状态,与产生它们的提供方和模型放在一起——响应级事实加每个流式块一条逐块条目。请求时,`LlmRuntime` 仅当同一适配器实例拥有两条路由时才传递回放状态;适配器校验它并恢复原生响应 id、提供方签名与可选的 `providerThinkingLevel` effort 元数据,缺失的 effort 元数据仍保持缺失。回放会对照 assistant 来源校验请求模型身份,并在提供方解析别名或回退时单独恢复 Anthropic 响应模型。回放状态缺失或无法使用时会降级为提供方无关内容,并保留 assistant 来源中必需的提供方和模型。pi-ai 工具调用参数是解析后的对象,因此适配器解析输入并重新字符串化输出,以符合 harness 原始 JSON 约定;pi-ai 流内错误事件映射为终止 `finish` 分片。 diff --git a/packages/llm/llm-pi-ai/src/context.ts b/packages/llm/llm-pi-ai/src/context.ts index d16e842845..84bfeab4f3 100644 --- a/packages/llm/llm-pi-ai/src/context.ts +++ b/packages/llm/llm-pi-ai/src/context.ts @@ -6,7 +6,7 @@ import { brandString } from '@deepseek-ai/dsh-brand' import { contentHasImage, IMAGE_OFFLOAD_REQUIRED_CODE, LlmError, offloadedImageText, projectOffloadedImages, requestImageHandleText, requiredImageOffload } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, GenerateOptions, ImageAttachmentAccessResolver, Message, ToolCallId } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, GenerateOptions, ImageAttachmentAccessResolver, Message, RequestMessage, ToolCallId } from '@deepseek-ai/dsh-llm' import type { AttachmentId, AttachmentStore, @@ -20,7 +20,7 @@ import { requestImageDimensions } from '@deepseek-ai/dsh-attachment' import { DEFAULT_REQUEST_IMAGE_MAX_BYTES, DEFAULT_REQUEST_IMAGE_PIXEL_BUDGET } from './config.ts' /** Join the text blocks of a harness message. */ -function flattenText(message: Message): string { +function flattenText(message: RequestMessage): string { return message.content .filter(block => block.type === 'text') .map(block => block.text) @@ -28,17 +28,33 @@ function flattenText(message: Message): string { } -/** Flatten text recursively inside one tool result. */ -function toolResultText(blocks: readonly ContentBlock[]): string { - return blocks.map(block => block.type === 'text' - ? block.text - : block.type === 'tool-result' ? toolResultText(block.content) : '').join('') +/** Recover the pi-ai toolResult message for one harness tool-role message. */ +function toolResultOf( + message: Extract, + toolNames: Map, + content: string | (TextContent | ImageContent)[], +): PiMessage { + return { + role: 'toolResult', + toolCallId: message.toolCallId, + toolName: toolNames.get(message.toolCallId) ?? 'unknown', + content: typeof content === 'string' + ? [{ type: 'text', text: content || '(no output)' }] + : content, + isError: message.isError ?? false, + timestamp: 0, + } } -/** Reject image roles that pi-ai cannot replay before request-size offloading can replace them. */ -function assertSupportedImageRoles(messages: readonly Message[]): void { +/** Reject unsupported roles, tool-change blocks, and image roles before replay or image offloading. */ +function assertSupportedHistory(messages: readonly RequestMessage[]): void { for (const message of messages) { - if (message.role !== 'user' && contentHasImage(message.content)) { + // Developer history is persisted for V4; provider serialization is intentionally deferred. + if (message.role === 'developer') throw new LlmError('Developer messages are not supported yet', 'UNSUPPORTED_CONTENT') + if (message.content.some(block => block.type === 'tool-addition' || block.type === 'tool-removal')) { + throw new LlmError('Tool-change blocks require developer role', 'UNSUPPORTED_CONTENT') + } + if (message.role !== 'user' && message.role !== 'tool' && contentHasImage(message.content)) { throw new LlmError( `pi-ai cannot represent an image in an in-history ${message.role} message`, 'UNSUPPORTED_CONTENT', @@ -47,11 +63,11 @@ function assertSupportedImageRoles(messages: readonly Message[]): void { } } -async function userContent( +function userContent( blocks: readonly ContentBlock[], requestImages: ReadonlyMap, resolveImageAccess: ImageAttachmentAccessResolver, -): Promise { +): string | (TextContent | ImageContent)[] { const content: (TextContent | ImageContent)[] = [] for (const block of blocks) { switch (block.type) { @@ -71,16 +87,6 @@ async function userContent( }) break } - case 'tool-result': - { - const nested = await userContent(block.content, requestImages, resolveImageAccess) - if (typeof nested === 'string') { - if (nested.length > 0) content.push({ type: 'text', text: nested }) - } else { - content.push(...nested) - } - } - break default: // Other merge-extensible blocks are not user-input vocabulary for pi-ai. break @@ -97,14 +103,12 @@ function collectImageRefs( for (const block of blocks) { if (block.type === 'image') { if (block.offloaded !== true) refs.set(block.attachment.attachmentId, block.attachment) - } else if (block.type === 'tool-result') { - collectImageRefs(block.content, refs) } } } async function prepareRequestImages( - messages: readonly Message[], + messages: readonly RequestMessage[], attachments: AttachmentStore, budget: PiImageRequestBudget, signal?: AbortSignal, @@ -123,6 +127,10 @@ async function prepareRequestImages( } function toolsOf(options: GenerateOptions): PiTool[] | undefined { + // Deferred definitions are persisted for V4; provider loading is intentionally deferred. + if (options.tools?.some(tool => tool.deferLoading === true)) { + throw new LlmError('Deferred tool loading is not supported yet', 'UNSUPPORTED_CONTENT') + } return options.tools?.map(tool => ({ name: tool.name, description: tool.description, @@ -137,7 +145,7 @@ interface SystemPromptSplit { /** Text for pi-ai's `systemPrompt`; `undefined` sends no system prompt. */ systemPrompt: string | undefined /** History messages that convert to pi-ai `messages`. */ - messages: readonly Message[] + messages: readonly RequestMessage[] } /** @@ -166,7 +174,7 @@ function piContext(systemPrompt: string | undefined, options: GenerateOptions, m } function appendAssistant( - message: Message, + message: Extract, messages: PiMessage[], toolNames: Map, onReplayDegrade?: (reason: string) => void, @@ -178,8 +186,28 @@ function appendAssistant( messages.push(assistant) } +/** Append the system and assistant roles both context builders treat identically; true when consumed. */ +function appendSystemOrAssistant( + message: RequestMessage, + messages: PiMessage[], + toolNames: Map, + onReplayDegrade?: (reason: string) => void, +): boolean { + if (message.role === 'system') { + // pi-ai has a single systemPrompt slot; a system message that did not + // supply it folds into a user message to preserve order. + messages.push({ role: 'user', content: flattenText(message), timestamp: 0 }) + return true + } + if (message.role === 'assistant') { + appendAssistant(message, messages, toolNames, onReplayDegrade) + return true + } + return false +} + function textOnlyContext(options: GenerateOptions, onReplayDegrade?: (reason: string) => void): PiContext { - assertSupportedImageRoles(options.messages) + assertSupportedHistory(options.messages) const split = splitSystemPrompt(options) const toolNames = new Map() const messages: PiMessage[] = [] @@ -187,32 +215,12 @@ function textOnlyContext(options: GenerateOptions, onReplayDegrade?: (reason: st if (contentHasImage(message.content)) { throw new LlmError('pi-ai image conversion requires the durable attachment service', 'UNSUPPORTED_CONTENT') } - if (message.role === 'system') { - // pi-ai has a single systemPrompt slot; a system message that did not - // supply it folds into a user message to preserve order. - messages.push({ role: 'user', content: flattenText(message), timestamp: 0 }) + if (appendSystemOrAssistant(message, messages, toolNames, onReplayDegrade)) continue + if (message.role === 'tool') { + messages.push(toolResultOf(message, toolNames, flattenText(message))) continue } - if (message.role === 'assistant') { - appendAssistant(message, messages, toolNames, onReplayDegrade) - continue - } - const text = flattenText(message) - const results = message.content.filter(block => block.type === 'tool-result') - if (text.length > 0 || results.length === 0) messages.push({ role: 'user', content: text, timestamp: 0 }) - for (const result of results) { - messages.push({ - role: 'toolResult', - toolCallId: result.toolCallId, - toolName: toolNames.get(result.toolCallId) ?? 'unknown', - content: [{ - type: 'text', - text: toolResultText(result.content) || '(no output)', - }], - isError: result.isError ?? false, - timestamp: 0, - }) - } + messages.push({ role: 'user', content: flattenText(message), timestamp: 0 }) } return piContext(split.systemPrompt, options, messages) } @@ -293,7 +301,7 @@ async function toPiContextWithImages( maxPixels: DEFAULT_REQUEST_IMAGE_PIXEL_BUDGET, maxBytes: DEFAULT_REQUEST_IMAGE_MAX_BYTES, } - assertSupportedImageRoles(options.messages) + assertSupportedHistory(options.messages) const split = splitSystemPrompt(options) const requestImages = await prepareRequestImages(split.messages, attachments, requestImagePolicy, options.signal) if (maxRequestImageBytes !== undefined) { @@ -318,38 +326,13 @@ async function toPiContextWithImages( const messages: PiMessage[] = [] for (const message of exactMessages) { - if (message.role === 'system') { - // pi-ai has a single systemPrompt slot; a system message that did not - // supply it folds into a user message to preserve order. - messages.push({ role: 'user', content: flattenText(message), timestamp: 0 }) + if (appendSystemOrAssistant(message, messages, toolNames, onReplayDegrade)) continue + if (message.role === 'tool') { + messages.push(toolResultOf(message, toolNames, userContent(message.content, requestImages, resolveImageAccess))) continue } - if (message.role === 'assistant') { - appendAssistant(message, messages, toolNames, onReplayDegrade) - continue - } - // user role: text + tool results (each result becomes its own message). - const regular = message.content.filter(block => block.type !== 'tool-result') - const content = await userContent(regular, requestImages, resolveImageAccess) - const results = message.content.filter((block): block is Extract => ( - block.type === 'tool-result' - )) - if (content.length > 0 || results.length === 0) { - messages.push({ role: 'user', content, timestamp: 0 }) - } - for (const result of results) { - const resultContent = await userContent(result.content, requestImages, resolveImageAccess) - messages.push({ - role: 'toolResult', - toolCallId: result.toolCallId, - toolName: toolNames.get(result.toolCallId) ?? 'unknown', - content: typeof resultContent === 'string' - ? [{ type: 'text', text: resultContent || '(no output)' }] - : resultContent, - isError: result.isError ?? false, - timestamp: 0, - }) - } + const content = userContent(message.content, requestImages, resolveImageAccess) + messages.push({ role: 'user', content, timestamp: 0 }) } return piContext(split.systemPrompt, options, messages) diff --git a/packages/llm/llm-pi-ai/src/replay.ts b/packages/llm/llm-pi-ai/src/replay.ts index 3e71c11f84..7df034522c 100644 --- a/packages/llm/llm-pi-ai/src/replay.ts +++ b/packages/llm/llm-pi-ai/src/replay.ts @@ -9,7 +9,7 @@ */ import { LlmError } from '@deepseek-ai/dsh-llm' -import type { Message, ModelMessageSource, ReplayEnvelope } from '@deepseek-ai/dsh-llm' +import type { AssistantMessage as HarnessAssistantMessage, ModelMessageSource, ReplayEnvelope } from '@deepseek-ai/dsh-llm' import type { Api, AssistantMessage, Usage as PiUsage } from '@earendil-works/pi-ai' /** Per-block half of the pi-ai replay envelope, one entry per content block. */ @@ -150,8 +150,8 @@ function readReplayState(value: unknown): PiAiReplayState { } /** Convert provider-neutral blocks without trusting them as same-model replay. */ -function foreignAssistant(message: Message): AssistantMessage { - const source = message.source.kind === 'model' ? message.source : undefined +function foreignAssistant(message: HarnessAssistantMessage): AssistantMessage { + const source = message.source const content: AssistantMessage['content'] = [] for (const block of message.content) { switch (block.type) { @@ -176,8 +176,8 @@ function foreignAssistant(message: Message): AssistantMessage { // Deliberately never equals a catalog API: absent replay state is foreign // even if source names the same provider/model as this request. api: 'dsh-foreign', - provider: source?.provider ?? 'dsh-foreign', - model: source?.model ?? 'dsh-foreign', + provider: source.provider, + model: source.model, usage: emptyPiUsage(), stopReason: content.some(piece => piece.type === 'toolCall') ? 'toolUse' : 'stop', timestamp: 0, @@ -185,7 +185,7 @@ function foreignAssistant(message: Message): AssistantMessage { } /** Recombine durable Harness content with validated pi-ai replay metadata. */ -function replayedAssistant(message: Message, source: ModelMessageSource, rawState: unknown): AssistantMessage { +function replayedAssistant(message: HarnessAssistantMessage, source: ModelMessageSource, rawState: unknown): AssistantMessage { const state = readReplayState(rawState) if (state.response.provider !== source.provider) return invalidReplay('provider does not match assistant source') if (state.response.model !== source.model) return invalidReplay('model does not match assistant source') @@ -241,14 +241,14 @@ function replayedAssistant(message: Message, source: ModelMessageSource, rawStat * another adapter's kind, another version, a malformed value, or metadata that * no longer matches the content — therefore degrades the one message to * provider-neutral history instead of failing the request. - * @param message - assistant content with required source and optional adapter-owned replay metadata. + * @param message - model-produced assistant content with provider, model, and optional adapter-owned replay metadata. * @param onDegrade - called with the diagnostic reason when an unusable replay * state falls back to provider-neutral conversion. * @returns a native pi-ai assistant message reconstructed from durable content. */ -export function toPiAssistant(message: Message, onDegrade?: (reason: string) => void): AssistantMessage { +export function toPiAssistant(message: HarnessAssistantMessage, onDegrade?: (reason: string) => void): AssistantMessage { const source = message.source - if (source.kind !== 'model' || source.replayState === undefined) return foreignAssistant(message) + if (source.replayState === undefined) return foreignAssistant(message) try { return replayedAssistant(message, source, source.replayState) } catch (error: unknown) { diff --git a/packages/llm/llm-pi-ai/tests/adapter.e2e.ts b/packages/llm/llm-pi-ai/tests/adapter.e2e.ts index b3190011cb..de8cd86532 100644 --- a/packages/llm/llm-pi-ai/tests/adapter.e2e.ts +++ b/packages/llm/llm-pi-ai/tests/adapter.e2e.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import LlmRuntime, { createUserMessage, ToolCallId, ReasoningEffortId } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createToolResultMessage, createUserMessage, ToolCallId, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import type { Message, ToolSchema } from '@deepseek-ai/dsh-llm' import * as LlmPiAi from '@deepseek-ai/dsh-llm-pi-ai' import type { PiAiProviderProfile } from '@deepseek-ai/dsh-llm-pi-ai' @@ -39,7 +39,7 @@ afterEach(async () => { function ask(text: string): Message[] { return [createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })] } @@ -127,13 +127,10 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('llm-pi-ai e2e (real API)', () => messages: [ ...ask('What is the weather in Paris right now? Use the get_weather tool.'), first.message, - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId(call!.id), - content: [{ type: 'text', text: 'Sunny, 22°C' }], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId(call!.id), + content: [{ type: 'text', text: 'Sunny, 22°C' }], + isError: false, }), ], tools: [weatherTool], diff --git a/packages/llm/llm-pi-ai/tests/adapter.spec.ts b/packages/llm/llm-pi-ai/tests/adapter.spec.ts index a247b20e42..1081125a7e 100644 --- a/packages/llm/llm-pi-ai/tests/adapter.spec.ts +++ b/packages/llm/llm-pi-ai/tests/adapter.spec.ts @@ -9,7 +9,7 @@ import type { SaveImageAttachment, StoredImageAttachment, } from '@deepseek-ai/dsh-attachment' -import LlmRuntime, { createUserMessage, CONTEXT_WINDOW_EXCEEDED_CODE, LlmError, ReasoningEffortId, userAgent } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createToolResultMessage, createUserMessage, CONTEXT_WINDOW_EXCEEDED_CODE, LlmError, ReasoningEffortId, userAgent } from '@deepseek-ai/dsh-llm' import * as LlmPiAi from '@deepseek-ai/dsh-llm-pi-ai' import { PiAiAdapter } from '@deepseek-ai/dsh-llm-pi-ai' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' @@ -80,7 +80,7 @@ describe('PiAiAdapter provider routing', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) expect(result.message.content).toEqual([{ type: 'text', text: 'hello' }]) @@ -319,7 +319,7 @@ describe('PiAiAdapter provider routing', () => { model: 'gpt-4.1', messages: [createUserMessage({ content: [{ type: 'image', attachment: ref }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], }) @@ -914,7 +914,7 @@ describe('provider profile lifecycle', () => { model: 'deepseek-v4-flash', messages: [createUserMessage({ content: [{ type: 'image', attachment: IMAGE_REF }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })).rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) await expect(drain({ @@ -922,23 +922,16 @@ describe('provider profile lifecycle', () => { model: 'gpt-4.1', messages: [createUserMessage({ content: [{ type: 'image', attachment: IMAGE_REF }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], })).rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) await expect(drain({ provider: 'openai', model: 'gpt-4.1', - messages: [createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: 'call-outer' as never, - content: [{ - type: 'tool-result', - toolCallId: 'call-inner' as never, - content: [{ type: 'image', attachment: IMAGE_REF }], - }], - }], - source: { kind: 'plugin', plugin: 'test' }, + messages: [createToolResultMessage({ + callId: 'call-outer' as never, + content: [{ type: 'image', attachment: IMAGE_REF }], + isError: false, })], })).rejects.toMatchObject({ code: 'UNSUPPORTED_CONTENT' }) }) diff --git a/packages/llm/llm-pi-ai/tests/assemble.ts b/packages/llm/llm-pi-ai/tests/assemble.ts index 8d415941c7..d22b4c2fb9 100644 --- a/packages/llm/llm-pi-ai/tests/assemble.ts +++ b/packages/llm/llm-pi-ai/tests/assemble.ts @@ -21,7 +21,6 @@ export async function assemble(ctx: Context, options: Omit { model: 'acme-large', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], }) diff --git a/packages/llm/llm-pi-ai/tests/context.spec.ts b/packages/llm/llm-pi-ai/tests/context.spec.ts index 47942b0099..181d10191c 100644 --- a/packages/llm/llm-pi-ai/tests/context.spec.ts +++ b/packages/llm/llm-pi-ai/tests/context.spec.ts @@ -6,12 +6,19 @@ import type { ImageRequestTarget, RequestImageAttachment, } from '@deepseek-ai/dsh-attachment' -import { ToolCallId, createMessage, createUserMessage, offloadedImageText } from '@deepseek-ai/dsh-llm' -import type { ContentBlock, GenerateOptions, Message } from '@deepseek-ai/dsh-llm' +import { createDeveloperMessage, ToolCallId, createAssistantMessage, createMessage, createToolResultMessage, createUserMessage, offloadedImageText } from '@deepseek-ai/dsh-llm' +import type { ContentBlock, GenerateOptions, Message, RequestUserInput } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { toPiContext } from '../src/context.ts' import type { PiImageRequestContext } from '../src/context.ts' import { toPiAssistant } from '../src/replay.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const ref: ImageAttachmentRef = { attachmentId: AttachmentId(`sha256:${'a'.repeat(64)}`), mediaType: 'image/png', @@ -67,33 +74,68 @@ function request(messages: GenerateOptions['messages']): GenerateOptions { } function user(content: ContentBlock[]): Message { - return createUserMessage({ content, source: { kind: 'plugin', plugin: 'test' } }) + return createUserMessage({ content, source: { kind: 'test' } }) } function history(role: 'system' | 'assistant', content: ContentBlock[]): Message { - return createMessage({ role, content, source: { kind: 'plugin', plugin: 'test' } }) + return role === 'system' + ? createMessage({ role, content, source: { kind: 'system-prompt' } }) + : createMessage({ role, content, source: { kind: 'model', provider: 'openai', model: 'gpt-4.1' } }) } describe('pi-ai request context conversion', () => { + it.each(['user', 'system', 'assistant', 'tool'] as const)('rejects tool-change blocks in %s history', (role) => { + for (const type of ['tool-addition', 'tool-removal'] as const) { + const message = { id: 'invalid', role, source: { kind: 'test' }, content: [{ type, toolName: 'search' }] } as unknown as Message + expect(() => toPiContext(request([message]))).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + } + }) + + it('rejects deferred tool definitions until provider loading is implemented', () => { + expect(() => toPiContext({ ...request([]), tools: [{ name: 'search', description: '', parameters: {}, deferLoading: true }] })) + .toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) + }) + + it('preserves the exact context for request-only input after durable tool history', async () => { + const prefix = [ + history('assistant', [{ type: 'tool-call', id: ToolCallId('lookup'), name: 'lookup', arguments: '{}' }]), + createToolResultMessage({ callId: ToolCallId('lookup'), content: [{ type: 'text', text: 'result' }], isError: false }), + ] + const input: RequestUserInput = { role: 'user', content: [{ type: 'text', text: 'review or summarize this input' }] } + const durable = createUserMessage({ content: input.content, source: { kind: 'test' } }) + expect(toPiContext(request([...prefix, input]))).toEqual(toPiContext(request([...prefix, durable]))) + const withImage: RequestUserInput = { role: 'user', content: [ + { type: 'text', text: 'before' }, { type: 'image', attachment: ref }, { type: 'text', text: 'after' }, + ] } + const durableImage = createUserMessage({ content: withImage.content, source: { kind: 'test' } }) + expect(await toPiContext(request([...prefix, withImage]), imageContext(attachments))) + .toEqual(await toPiContext(request([...prefix, durableImage]), imageContext(attachments))) + expect(withImage).not.toHaveProperty('id') + expect(withImage).not.toHaveProperty('source') + }) + + it('rejects developer history before reading image attachments', async () => { + const read = vi.fn((value: ImageAttachmentRef) => Promise.resolve(requestImage(value, Uint8Array.of(1)))) + const message = createDeveloperMessage({ content: [{ type: 'tool-addition', toolName: 'search' }], source: { kind: 'test' } }) + const failure = { code: 'UNSUPPORTED_CONTENT', message: 'Developer messages are not supported yet' } + expect(() => toPiContext(request([message]))).toThrow(expect.objectContaining(failure)) + await expect(toPiContext(request([message]), imageContext(projectionStore(read)))).rejects.toMatchObject(failure) + expect(read).not.toHaveBeenCalled() + }) + it('omits absent and empty request-level optional fields', () => { const base = { provider: 'openai', model: 'gpt-4.1', messages: [] } expect(toPiContext(base)).toEqual({ messages: [] }) expect(toPiContext({ ...base, tools: [] })).toEqual({ messages: [] }) }) - it('converts complete text-only history and rejects nested images without storage', () => { + it('converts complete text-only history and rejects tool images without storage', () => { const callId = ToolCallId('call-1') expect(toPiContext(request([ history('system', [{ type: 'text', text: 'history system' }]), history('assistant', [{ type: 'tool-call', id: callId, name: 'lookup', arguments: '{}' }]), - user([ - { type: 'text', text: 'after tool' }, - { - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text: '' }], - }, - ]), + user([{ type: 'text', text: 'after tool' }]), + createToolResultMessage({ callId, content: [{ type: 'text', text: '' }], isError: false }), ]))).toMatchObject({ systemPrompt: 'system prompt', tools: [{ name: 'lookup' }], @@ -111,11 +153,9 @@ describe('pi-ai request context conversion', () => { ], }) - expect(() => toPiContext(request([user([{ - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'image', attachment: ref }], - }])]))).toThrow(/durable attachment service/) + expect(() => toPiContext(request([ + createToolResultMessage({ callId, content: [{ type: 'image', attachment: ref }], isError: false }), + ]))).toThrow(/durable attachment service/) }) it('resolves user and tool-result images while preserving explicit fallbacks', async () => { @@ -132,20 +172,12 @@ describe('pi-ai request context conversion', () => { { type: 'text', text: 'caption' }, { type: 'reasoning', text: 'ignored' }, ]), - user([{ - type: 'tool-result', - toolCallId: knownCallId, - content: [{ type: 'text', text: '' }], - }]), - user([{ - type: 'tool-result', - toolCallId: callId, + createToolResultMessage({ callId: knownCallId, content: [{ type: 'text', text: '' }], isError: false }), + createToolResultMessage({ + callId, + content: [{ type: 'image', attachment: ref }], isError: true, - content: [ - { type: 'tool-result', toolCallId: callId, content: [] }, - { type: 'image', attachment: ref }, - ], - }]), + }), ]), imageContext(attachments)) expect(context.messages).toEqual([ @@ -203,24 +235,30 @@ describe('pi-ai request context conversion', () => { expect(JSON.stringify(context.messages[0])).toContain('request preview 1130x565px') }) - it('recursively converts nested tool-result text and images', async () => { - const callId = ToolCallId('nested-call') - const context = await toPiContext(request([user([{ - type: 'tool-result', + it('treats a tool message without isError as a successful result', () => { + const callId = ToolCallId('default-success') + const message = createMessage({ + role: 'tool', + source: { kind: 'tool', callId }, toolCallId: callId, + content: [{ type: 'text', text: 'result' }], + }) + expect(toPiContext(request([message])).messages).toEqual([{ + role: 'toolResult', toolCallId: callId, toolName: 'unknown', + content: [{ type: 'text', text: 'result' }], isError: false, timestamp: 0, + }]) + }) + + it('converts tool text and images on the image path', async () => { + const callId = ToolCallId('nested-call') + const context = await toPiContext(request([createToolResultMessage({ + callId, content: [ - { - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text: 'nested text' }], - }, - { - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'image', attachment: ref }], - }, + { type: 'text', text: 'nested text' }, + { type: 'image', attachment: ref }, ], - }])]), imageContext(attachments)) + isError: false, + })]), imageContext(attachments)) expect(context.messages).toEqual([{ role: 'toolResult', @@ -236,20 +274,18 @@ describe('pi-ai request context conversion', () => { }]) }) - it('flattens nested text-only tool results and ignores other block types without storage', () => { + it('flattens tool text and ignores other block types without storage', () => { const callId = ToolCallId('nested-text') - expect(toPiContext(request([user([{ - type: 'tool-result', - toolCallId: callId, - content: [ - { type: 'chart', data: 'ignored' } as unknown as ContentBlock, - { - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text: 'nested' }], - }, - ], - }])]))).toMatchObject({ + expect(toPiContext(request([ + createToolResultMessage({ + callId, + content: [ + { type: 'chart', data: 'ignored' } as unknown as ContentBlock, + { type: 'text', text: 'nested' }, + ], + isError: false, + }), + ]))).toMatchObject({ messages: [{ role: 'toolResult', content: [{ type: 'text', text: 'nested' }], @@ -264,14 +300,14 @@ describe('pi-ai request context conversion', () => { const store = projectionStore(readImageRequest) const sized: ImageAttachmentRef = { ...ref, bytes: 3 } const callId = ToolCallId('shot-call') - // The nested occurrence is offloaded on the surface; the two retained 3-byte images cost + // The tool-result occurrence is offloaded on the surface; the two retained 3-byte images cost // 4 base64 characters each and fit the 8-byte bound exactly. const context = await toPiContext(request([ - user([{ - type: 'tool-result', - toolCallId: callId, + createToolResultMessage({ + callId, content: [{ type: 'image', attachment: sized, offloaded: true }], - }]), + isError: false, + }), user([{ type: 'image', attachment: sized }, { type: 'text', text: 'newer' }]), user([{ type: 'image', attachment: sized }]), ]), imageContext(store, { maxRequestImageBytes: 8 })) @@ -426,11 +462,7 @@ describe('pi-ai request context conversion', () => { { type: 'text', text: 'answer' }, { type: 'tool-call', id: ToolCallId('other-call'), name: 'lookup', arguments: '{}' }, ]), - user([{ - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text: 'result' }], - }]), + createToolResultMessage({ callId, content: [{ type: 'text', text: 'result' }], isError: false }), ]))).toMatchObject({ messages: [ { role: 'user', content: '' }, @@ -463,7 +495,10 @@ describe('pi-ai request context conversion', () => { }) expect(() => toPiAssistant( - history('assistant', [{ type: 'image', attachment: ref }]), + createAssistantMessage({ + content: [{ type: 'image', attachment: ref }], + source: { provider: 'openai', model: 'gpt-4.1' }, + }), )).toThrow(/assistant image output/) }) @@ -477,14 +512,6 @@ describe('pi-ai system prompt source', () => { it.each<{ label: string; content: ContentBlock[] }>([ { label: 'image-only', content: [{ type: 'image', attachment: ref }] }, { label: 'text and image', content: [{ type: 'text', text: 'rule' }, { type: 'image', attachment: ref }] }, - { - label: 'nested image', - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('system-image'), - content: [{ type: 'image', attachment: ref }], - }], - }, ])('rejects a leading system $label on both conversion paths', async ({ content }) => { const options: GenerateOptions = { ...base, messages: [history('system', content), question] } const error = { diff --git a/packages/llm/llm-pi-ai/tests/convert.spec.ts b/packages/llm/llm-pi-ai/tests/convert.spec.ts index 4347d74858..4ca36d762a 100644 --- a/packages/llm/llm-pi-ai/tests/convert.spec.ts +++ b/packages/llm/llm-pi-ai/tests/convert.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest' import { AttachmentId, ImageVariantId } from '@deepseek-ai/dsh-attachment' import type { AttachmentStore, ImageAttachmentRef, ImageRequestTarget, RequestImageAttachment } from '@deepseek-ai/dsh-attachment' -import { createUserMessage, ToolCallId, CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, createMessage } from '@deepseek-ai/dsh-llm' +import { createToolResultMessage, createUserMessage, ToolCallId, CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, createMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, StreamChunk } from '@deepseek-ai/dsh-llm' import type { AssistantMessage, AssistantMessageEvent, Usage } from '@earendil-works/pi-ai' import { transformMessages } from '@earendil-works/pi-ai/api/transform-messages' @@ -80,7 +80,7 @@ describe('toPiContext', () => { system: 'be helpful', messages: [createUserMessage({ content: [{ type: 'text', text: 'hi' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], tools: [{ name: 'f', description: 'F', parameters: { type: 'object', properties: {} } }], }) @@ -113,7 +113,7 @@ describe('toPiContext', () => { model: 'gpt-4.1', messages: [createUserMessage({ content: [{ type: 'text', text: 'describe' }, { type: 'image', attachment }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], }, imageContext(attachmentStore(readImageRequest))) @@ -133,7 +133,7 @@ describe('toPiContext', () => { }) }) - it('flattens nested tool-result images into the enclosing result', async () => { + it('converts a tool message with text and images on the image path', async () => { const attachment = { attachmentId: AttachmentId(`sha256:${'c'.repeat(64)}`), mediaType: 'image/png' as const, @@ -147,25 +147,15 @@ describe('toPiContext', () => { const context = await toPiContext({ provider: 'openai', model: 'gpt-4.1', - messages: [createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('outer'), - content: [ - { type: 'tool-result', toolCallId: ToolCallId('empty'), content: [] }, - { type: 'text', text: 'before' }, - { type: 'tool-result', toolCallId: ToolCallId('text'), content: [{ type: 'text', text: 'middle' }] }, - { - type: 'tool-result', - toolCallId: ToolCallId('inner'), - content: [ - { type: 'image', attachment }, - { type: 'text', text: 'after' }, - ], - }, - ], - }], - source: { kind: 'plugin', plugin: 'test' }, + messages: [createToolResultMessage({ + callId: ToolCallId('outer'), + content: [ + { type: 'text', text: 'before' }, + { type: 'text', text: 'middle' }, + { type: 'image', attachment }, + { type: 'text', text: 'after' }, + ], + isError: false, })], }, imageContext(attachmentStore(readImageRequest))) @@ -196,7 +186,7 @@ describe('toPiContext', () => { mediaType: 'image/png', bytes: 1, width: 1, height: 1, }, }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })).toThrow(expect.objectContaining({ code: 'UNSUPPORTED_CONTENT' })) }) @@ -212,7 +202,7 @@ describe('toPiContext', () => { { type: 'text', text: 'calling' }, { type: 'tool-call', id: ToolCallId('c1'), name: 'f', arguments: '{"a":1}' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek', model: 'm' }, })], }) const message = context.messages[0] as AssistantMessage @@ -231,7 +221,7 @@ describe('toPiContext', () => { model: 'm', messages: [createMessage({ role: 'assistant', content: [{ type: 'text', text: 'done' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek', model: 'm' }, })], }) expect((context.messages[0] as AssistantMessage).stopReason).toBe('stop') @@ -262,7 +252,7 @@ describe('toPiContext', () => { messages: [createMessage({ role: 'assistant', content: [{ type: 'tool-call', id: ToolCallId('c1'), name: 'f', arguments: '{broken' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek', model: 'm' }, })], }) const message = context.messages[0] as AssistantMessage @@ -276,7 +266,7 @@ describe('toPiContext', () => { messages: [createMessage({ role: 'assistant', content: [{ type: 'tool-call', id: ToolCallId('c1'), name: 'f', arguments: '[1,2]' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek', model: 'm' }, })], }) expect((context.messages[0] as AssistantMessage).content[0]).toMatchObject({ arguments: {} }) @@ -290,19 +280,16 @@ describe('toPiContext', () => { createMessage({ role: 'assistant', content: [{ type: 'tool-call', id: ToolCallId('c1'), name: 'get_weather', arguments: '{}' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek', model: 'm' }, }), - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('c1'), - content: [ - { type: 'text', text: 'Sunny' }, - { type: 'tool-result', toolCallId: ToolCallId('nested'), content: [{ type: 'text', text: '!' }] }, - { type: 'chart', data: 'ignored' } as unknown as ContentBlock, - ], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId('c1'), + content: [ + { type: 'text', text: 'Sunny' }, + { type: 'text', text: '!' }, + { type: 'chart', data: 'ignored' } as unknown as ContentBlock, + ], + isError: false, }), ], }) @@ -320,10 +307,7 @@ describe('toPiContext', () => { const context = toPiContext({ provider: 'deepseek', model: 'm', - messages: [createUserMessage({ - content: [{ type: 'tool-result', toolCallId: ToolCallId('zz'), content: [], isError: true }], - source: { kind: 'plugin', plugin: 'test' }, - })], + messages: [createToolResultMessage({ callId: ToolCallId('zz'), content: [], isError: true })], }) expect(context.messages[0]).toMatchObject({ role: 'toolResult', @@ -340,14 +324,16 @@ describe('toPiContext', () => { messages: [ createMessage({ role: 'system', content: [{ type: 'text', text: 'rule' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'system-prompt' }, }), createUserMessage({ - content: [ - { type: 'text', text: 'note' }, - { type: 'tool-result', toolCallId: ToolCallId('c1'), content: [{ type: 'text', text: 'ok' }] }, - ], - source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'note' }], + source: { kind: 'model', provider: 'deepseek', model: 'm' }, + }), + createToolResultMessage({ + callId: ToolCallId('c1'), + content: [{ type: 'text', text: 'ok' }], + isError: false, }), ], }) @@ -365,7 +351,7 @@ describe('toPiContext', () => { { type: 'chart', data: 'x' } as unknown as ContentBlock, { type: 'text', text: 'visible' }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek', model: 'm' }, })], }) expect((context.messages[0] as AssistantMessage).content).toEqual([{ type: 'text', text: 'visible' }]) diff --git a/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts b/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts index fd917c7a66..21aacab18f 100644 --- a/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts +++ b/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts @@ -10,7 +10,7 @@ import type { SaveImageAttachment, StoredImageAttachment, } from '@deepseek-ai/dsh-attachment' -import LlmRuntime, { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import LlmRuntime, { createToolResultMessage, createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' import type { Message, ToolSchema } from '@deepseek-ai/dsh-llm' import * as LlmPiAi from '@deepseek-ai/dsh-llm-pi-ai' import type { PiAiReplayResponse } from '../src/replay.ts' @@ -121,7 +121,7 @@ afterEach(async () => { function ask(text: string): Message[] { return [createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })] } @@ -209,13 +209,10 @@ for (const profile of providerCases) { messages: [ ...prompt, first.message, - createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: ToolCallId(call!.id), - content: [{ type: 'text', text: 'The code blue means ocean.' }], - }], - source: { kind: 'plugin', plugin: 'test' }, + createToolResultMessage({ + callId: ToolCallId(call!.id), + content: [{ type: 'text', text: 'The code blue means ocean.' }], + isError: false, }), ], tools: [lookupTool], @@ -252,7 +249,7 @@ for (const profile of providerCases) { }, { type: 'image', attachment: ref }, ], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'deepseek-official', model: 'deepseek-v4-flash' }, })], maxTokens: 256, }) diff --git a/packages/llm/llm/README.i18n.yaml b/packages/llm/llm/README.i18n.yaml index c105e97d77..6fac0fb24a 100644 --- a/packages/llm/llm/README.i18n.yaml +++ b/packages/llm/llm/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/llm/llm/README.md -README.md: 7192ee58eaffb153231268095feb3d9c7ddda37a -README.zh.md: 6898833c6eb5199ce8a93b7ec33cbf4ce7a31cb3 +README.md: cdda682cebc720d51692a1b0c4c8691fa84359a3 +README.zh.md: 8c679ecc6910376f7270450ae5be867d0da353fc diff --git a/packages/llm/llm/README.md b/packages/llm/llm/README.md index 7192ee58ea..cdda682ceb 100644 --- a/packages/llm/llm/README.md +++ b/packages/llm/llm/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -Use `@deepseek-ai/dsh-llm` to stream model calls through configured provider adapters, discover models, and resolve model capabilities and call defaults. Every dispatched request remains reconstructable from the session log. Requests are deep-frozen before dispatch, so extensions and adapters can read them but cannot rewrite them. Each stream is one provider attempt: provider-specific translation stays with its adapter, while the optional `@deepseek-ai/dsh-llm-retry` package re-runs failed requests. Streams always end with a terminal result, so callers can handle success, failure, and cancellation consistently. +Use `@deepseek-ai/dsh-llm` to stream model calls through configured provider adapters, discover models, and resolve model capabilities and call defaults. Callers must keep all model-visible input reconstructable from the session log. Loop-built requests arrive deep-frozen, so extensions and adapters cannot rewrite them. Each stream is one provider attempt: provider-specific translation stays with its adapter, while the optional `@deepseek-ai/dsh-llm-retry` package re-runs failed requests. Streams always end with a terminal result, so callers can handle success, failure, and cancellation consistently. ## Table of Contents @@ -48,7 +48,7 @@ A stream returns token-level chunks and always ends with one terminal `finish` c for await (const chunk of ctx.llm.stream({ provider: 'deepseek-official', model: 'deepseek-v4-flash', - messages: [createUserMessage({ content: [{ type: 'text', text: 'Hello' }] })], + messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }], })) { // chunks: block-start, text-delta, ..., usage, finish } @@ -56,6 +56,8 @@ for await (const chunk of ctx.llm.stream({ After a successful mount, `ctx.llm.listProviders()` reports the registered routes in registration order. +`GenerateOptions.messages` accepts durable `Message` values and request-only `RequestUserInput` values. Request-only inputs carry user-role content with no `id` or `source`; Session writes and Agent delivery still require durable messages. Callers keep auxiliary inputs unchanged until the stream settles. A caller that records its exact request, such as session-title generation, must use durable messages. + ### What you can do - **Stream one model call** — `ctx.llm.stream(options)` yields raw chunks (token-level deltas) for any registered provider and model; consumers assemble them with `BlockAssembler`. @@ -81,7 +83,7 @@ This section explains the design behind the service; the observable behavior is ### Design philosophy -The service is built on one separation: **the logical contract is provider-neutral, adapters own the wire.** It defines the canonical message, content-block, and stream-chunk vocabulary once, and every provider adapter translates only its own wire format into that vocabulary. The registry is the topology owner — adapter routes, configurable-provider entries, and discovery offers all register here and are disposed with their fiber — while a request stays a pure function of the session log: loop-built requests arrive deep-frozen, so listeners and adapters read them and never rewrite them. +The service is built on one separation: **the logical contract is provider-neutral, adapters own the wire.** It defines the canonical message, content-block, and stream-chunk vocabulary once, and every provider adapter translates only its own wire format into that vocabulary. The registry is the topology owner — adapter routes, configurable-provider entries, and discovery offers all register here and are disposed with their fiber — while an agent-loop request stays a pure function of the session log: loop-built requests arrive deep-frozen, so listeners and adapters read them and never rewrite them. ### Source map @@ -101,13 +103,13 @@ The service is built on one separation: **the logical contract is provider-neutr ### Main flow -A request is validated against its exact model's capability — context window, output default, reasoning efforts, input modalities, and `systemPromptUpdate` mode — and any adapter-configured defaults are materialized, then the whole request is deep-frozen. `prepareCall()` binds those facts, detached context, and retry policy to the exact adapter generation that performs terminal dispatch, so HMR or dynamic settings cannot combine one generation's image capability with another generation's endpoint. An image-capable adapter projects durable references into route-specific request versions; `resolveImageAttachmentAccess()` separately maps an attachment provider's optional host object into the current tool execution world without changing the request image or its `variantId`. A text-only route receives deterministic per-image placeholders, including nested tool-result images, without rewriting append-only session history. Durable `FileBlock` references never reach any adapter: request assembly replaces each one, nested tool-result occurrences included, with deterministic handle text naming the file and its saved read-only path, resolved through the mounted attachment and filesystem providers. `ctx.llm.fileRequestText(ref)` exposes that exact synchronous projection to request measurement. An image occurrence derived with `offloaded: true` reaches every route as placeholder text through `projectOffloadedImages()`. An image-capable route whose retained occurrences exceed its `LlmImageRequestBudget` at their exact bytes fails with `IMAGE_OFFLOAD_REQUIRED` naming the additional oldest occurrences (`requiredImageOffload()`), never with an unlogged projection; `dsh-compaction-image-offload` logs the selected occurrences in one `image/offload` event and retries. Adapters that charge visual tokens declare per-route `imageRequestPricing`, which `ctx.llm.imageRequestPricing(provider, model)` resolves synchronously for the token meter. Dispatch goes through the `llm/stream` waterfall, then chunks return as token-level deltas and every adapter outcome reaches the consumer as one terminal `finish` chunk. +A request is validated against its exact model's capability — context window, output default, reasoning efforts, input modalities, and `systemPromptUpdate` mode — and any adapter-configured defaults are materialized. The runtime preserves freezing for already-frozen input; hand-built callers own input immutability. `prepareCall()` binds those facts, detached context, and retry policy to the exact adapter generation that performs terminal dispatch, so HMR or dynamic settings cannot combine one generation's image capability with another generation's endpoint. An image-capable adapter projects durable references into route-specific request versions; `resolveImageAttachmentAccess()` separately maps an attachment provider's optional host object into the current tool execution world without changing the request image or its `variantId`. A text-only route receives deterministic per-image placeholders, including tool-role result images, without rewriting append-only session history. Durable `FileBlock` references never reach any adapter: request assembly replaces each one, including tool-role result occurrences, with deterministic handle text naming the file and its saved read-only path, resolved through the mounted attachment and filesystem providers. `ctx.llm.fileRequestText(ref)` exposes that exact synchronous projection to request measurement. An image occurrence derived with `offloaded: true` reaches every route as placeholder text through `projectOffloadedImages()`. An image-capable route whose retained occurrences exceed its `LlmImageRequestBudget` at their exact bytes fails with `IMAGE_OFFLOAD_REQUIRED` naming the additional oldest occurrences (`requiredImageOffload()`), never with an unlogged projection; `dsh-compaction-image-offload` logs the selected occurrences in one `image/offload` event and retries. Adapters that charge visual tokens declare per-route `imageRequestPricing`, which `ctx.llm.imageRequestPricing(provider, model)` resolves synchronously for the token meter. Dispatch goes through the `llm/stream` waterfall, then chunks return as token-level deltas and every adapter outcome reaches the consumer as one terminal `finish` chunk. -File detection reads current content, including nested tool results, on every request without caching message identities or freeze state. The [file-scan decision](../../../.agents/notes/implemented/simplification/2026-09-07-file-content-scan.md) records the measured traversal cost. +File detection reads current content, including tool-role result content, on every request without caching message identities or freeze state. The [file-scan decision](../../../.agents/notes/implemented/simplification/2026-09-07-file-content-scan.md) records the measured traversal cost. ### Invariants -- **Model-visible ⟺ logged** — anything that reaches a provider request is reconstructable from the session log; loop-built requests are deep-frozen and never rewritten. +- **Model-visible ⟺ logged** — callers must keep every provider request's model-visible input reconstructable from the session log; loop-built requests arrive deep-frozen and cannot be rewritten. - **Replay state travels only within one adapter** — assistant replay state rides along only when the same adapter instance owns the historical and target routes; otherwise it is dropped before dispatch. - **Prepared calls are one-shot** — a prepared call can be dispatched exactly once, and its call-config fields must match the prepared config. - **Image projection follows the captured route** — durable `ImageBlock` references become route-specific request versions only for image-capable models; text-only models receive stable placeholders. @@ -152,9 +154,10 @@ These limits define where this service stops and other packages or future work b - **No retry execution, caching, or rate limiting ships in this service** — provider registration stores the retry policy, but a stream remains a single provider attempt; `@deepseek-ai/dsh-llm-retry` executes the policy at durable agent-step boundaries. - **`GenerateOptions` sampling is `temperature`/`maxTokens`/`stop` only** — no `tool_choice`, `top_p`, or penalty fields; the vocabulary grows when a producer lands ([dropped inert knobs](../../../.agents/notes/archived/simplification/2026-07-04-drop-inert-request-knobs.md)). -- **Producer-gated variants stay out until produced** — `prefill`, per-tool `strict`, block `cache` hints, and the `agent` message-source variant have no producer ([Agent Note](../../../.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md)). +- **Variants normally require a producer** — `prefill`, per-tool `strict`, block `cache` hints, and the `agent` message-source variant have no producer ([Agent Note](../../../.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md)). - **`BlockAssembler` handles core block kinds only** — a plugin-added block type whose stream is never closed by `block-end` makes `blocks()` throw. - **`GenerateOptions.sessionId` is a locally-declared brand** — importing dsh-session's `SessionId` would create a dependency cycle. +- **Session-change types are a V4 persistence exception** — `DeveloperMessage` carries incremental session changes. Additions and removals name tools; the containing Session event binds additions to a historical request header that owns their definitions. See [Session references](../../core/session/README.md) for admission and restoration. Provider serialization, deferred loading, and UI presentation remain deferred. Both DeepSeek protocols and pi-ai reject developer history and `deferLoading` requests; Chat and Trajectory reject developer events. Ordinary requests retain their existing behavior. ### Dev Note diff --git a/packages/llm/llm/README.zh.md b/packages/llm/llm/README.zh.md index 6898833c6e..8c679ecc69 100644 --- a/packages/llm/llm/README.zh.md +++ b/packages/llm/llm/README.zh.md @@ -9,7 +9,7 @@ kind: "package-reference" ## 概述 -使用 `@deepseek-ai/dsh-llm` 可通过已配置的提供方适配器流式调用模型、发现模型,并解析模型能力与调用默认值。每个已分发请求都可以从会话日志重建。请求在分发前会被深度冻结,因此扩展与适配器可以读取但不能改写。每个流只尝试调用提供方一次:提供方特定的转换由对应适配器完成,可选包 `@deepseek-ai/dsh-llm-retry` 负责重跑失败的请求。流始终以终止结果结束,因此调用方可以一致地处理成功、失败与取消。 +使用 `@deepseek-ai/dsh-llm` 可通过已配置的提供方适配器流式调用模型、发现模型,并解析模型能力与调用默认值。调用方必须确保所有模型可见输入都可以从会话日志重建。Loop 构建的请求以深度冻结状态到达,因此扩展与适配器不能改写。每个流只尝试调用提供方一次:提供方特定的转换由对应适配器完成,可选包 `@deepseek-ai/dsh-llm-retry` 负责重跑失败的请求。流始终以终止结果结束,因此调用方可以一致地处理成功、失败与取消。 ## 目录 @@ -48,7 +48,7 @@ kind: "package-reference" for await (const chunk of ctx.llm.stream({ provider: 'deepseek-official', model: 'deepseek-v4-flash', - messages: [createUserMessage({ content: [{ type: 'text', text: 'Hello' }] })], + messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }], })) { // chunks: block-start, text-delta, ..., usage, finish } @@ -56,6 +56,8 @@ for await (const chunk of ctx.llm.stream({ 挂载成功后,`ctx.llm.listProviders()` 会按注册顺序报告已注册路由。 +`GenerateOptions.messages` 接受持久 `Message` 值和仅供请求使用的 `RequestUserInput` 值。仅供请求使用的输入包含 user-role 内容,不含 `id` 或 `source`;Session 写入和 Agent 投递仍然要求持久消息。调用方必须在流结束前保持辅助输入不变。会记录完整请求的调用方(例如会话标题生成)必须使用持久消息。 + ### 你可以做什么 - **流式发起一次模型调用**——`ctx.llm.stream(options)` 为任何已注册提供方与模型产出原始分片(token 级增量);消费方用 `BlockAssembler` 组装。 @@ -81,7 +83,7 @@ for await (const chunk of ctx.llm.stream({ ### 设计理念 -本服务基于一项职责分离原则:**逻辑约定是提供方无关的,适配器拥有协议。** 它一次性地定义规范消息、内容块与流式分片词汇,每个提供方适配器只把自己的协议格式翻译为该词汇。注册表是拓扑的拥有者——适配器路由、可配置提供方条目与发现 offer 都在这里注册,并随其 fiber 一起 dispose(资源释放)——而请求始终是会话日志的纯函数:loop 构建的请求以深度冻结状态到达,因此监听器与适配器只能读取,绝不能改写。 +本服务基于一项职责分离原则:**逻辑约定是提供方无关的,适配器拥有协议。** 它一次性地定义规范消息、内容块与流式分片词汇,每个提供方适配器只把自己的协议格式翻译为该词汇。注册表是拓扑的拥有者——适配器路由、可配置提供方条目与发现 offer 都在这里注册,并随其 fiber 一起 dispose(资源释放)——而 agent loop 的请求始终是会话日志的纯函数:loop 构建的请求以深度冻结状态到达,因此监听器与适配器只能读取,绝不能改写。 ### 源码地图 @@ -101,13 +103,13 @@ for await (const chunk of ctx.llm.stream({ ### 主流程 -请求会对照其精确模型的能力校验,包括上下文窗口、输出默认值、推理强度、输入模态与 `systemPromptUpdate` 模式,填入任何适配器配置的默认值,然后整个请求被深度冻结。`prepareCall()` 把这些事实、分离的上下文与重试策略绑定到执行最终分发的精确适配器代次,因此 HMR(热模块替换)或动态设置无法把一个代次的图片能力与另一代次的端点混用。支持图片的适配器把持久引用投影为路由专用请求版本;`resolveImageAttachmentAccess()` 会单独把附件提供方的可选宿主对象映射进当前工具执行世界,而不改变请求图片或其 `variantId`。纯文本路由接收确定性的逐图片占位符,包括嵌套工具结果图片,而不会改写仅追加会话历史。持久 `FileBlock` 引用永远不会到达任何适配器:请求组装把每个引用(包括嵌套工具结果中的出现)替换为确定性 句柄文本,指出文件与其只读保存路径,路径经由挂载的附件与文件系统提供方解析。`ctx.llm.fileRequestText(ref)` 向请求计量公开相同的同步投影。派生后带有 `offloaded: true` 的图片出现位置,经 `projectOffloadedImages()` 以占位文本到达每条路由。支持图片的路由在保留的出现位置按精确字节超过其 `LlmImageRequestBudget` 时,以 `IMAGE_OFFLOAD_REQUIRED` 失败并说明还需省略多少最老的出现位置(`requiredImageOffload()`),绝不发送未记录的投影;`dsh-compaction-image-offload` 用一条 `image/offload` 事件记录所选位置并重试。对视觉 token 收费的适配器声明按路由的 `imageRequestPricing`,`ctx.llm.imageRequestPricing(provider, model)` 为 token meter 同步解析它。分发经过 `llm/stream` waterfall(瀑布式事件),随后分片以 token 级增量返回,每个适配器结果都以唯一一个终止 `finish` 分片到达消费方。 +请求会对照其精确模型的能力校验,包括上下文窗口、输出默认值、推理强度、输入模态与 `systemPromptUpdate` 模式,并填入任何适配器配置的默认值。运行时保留已冻结输入的冻结状态;手动构建请求的调用方负责保证输入不可变。`prepareCall()` 把这些事实、分离的上下文与重试策略绑定到执行最终分发的精确适配器代次,因此 HMR(热模块替换)或动态设置无法把一个代次的图片能力与另一代次的端点混用。支持图片的适配器把持久引用投影为路由专用请求版本;`resolveImageAttachmentAccess()` 会单独把附件提供方的可选宿主对象映射进当前工具执行世界,而不改变请求图片或其 `variantId`。纯文本路由接收确定性的逐图片占位符,包括 tool-role 结果图片,而不会改写仅追加会话历史。持久 `FileBlock` 引用永远不会到达任何适配器:请求组装把每个引用(包括 tool-role 结果中的出现)替换为确定性句柄文本,指出文件与其只读保存路径,路径经由挂载的附件与文件系统提供方解析。`ctx.llm.fileRequestText(ref)` 向请求计量公开相同的同步投影。派生后带有 `offloaded: true` 的图片出现位置,经 `projectOffloadedImages()` 以占位文本到达每条路由。支持图片的路由在保留的出现位置按精确字节超过其 `LlmImageRequestBudget` 时,以 `IMAGE_OFFLOAD_REQUIRED` 失败并说明还需省略多少最老的出现位置(`requiredImageOffload()`),绝不发送未记录的投影;`dsh-compaction-image-offload` 用一条 `image/offload` 事件记录所选位置并重试。对视觉 token 收费的适配器声明按路由的 `imageRequestPricing`,`ctx.llm.imageRequestPricing(provider, model)` 为 token meter 同步解析它。分发经过 `llm/stream` waterfall(瀑布式事件),随后分片以 token 级增量返回,每个适配器结果都以唯一一个终止 `finish` 分片到达消费方。 -文件检测在每次请求时读取当前内容,包括嵌套工具结果,不缓存消息身份或冻结状态。[文件扫描决策](../../../.agents/notes/implemented/simplification/2026-09-07-file-content-scan.zh.md)记录了实测遍历成本。 +文件检测在每次请求时读取当前内容,包括 tool-role 结果内容,不缓存消息身份或冻结状态。[文件扫描决策](../../../.agents/notes/implemented/simplification/2026-09-07-file-content-scan.zh.md)记录了实测遍历成本。 ### 不变式 -- **模型可见 ⟺ 已记录**——到达提供方请求的任何内容都可以从会话日志重建;loop 构建的请求被深度冻结,绝不改写。 +- **模型可见 ⟺ 已记录**——调用方必须确保每个提供方请求中的模型可见输入都可以从会话日志重建;loop 构建的请求以深度冻结状态到达,不可改写。 - **回放状态只在同一适配器内流动**——仅当同一适配器实例同时拥有历史路由与目标路由时,assistant 回放状态才会随行;否则在分发前被丢弃。 - **已准备调用是一次性的**——已准备调用只能分发一次,且其调用配置字段必须与准备好的配置一致。 - **图片投影遵循捕获的路由**——只有支持图片的模型会把持久 `ImageBlock` 引用转换为路由专用请求版本;纯文本模型接收稳定占位符。 @@ -152,9 +154,10 @@ for await (const chunk of ctx.llm.stream({ - **本服务不提供重试执行、缓存或速率限制**——提供方注册会存储重试策略,但一次流仍是一次提供方尝试;`@deepseek-ai/dsh-llm-retry` 在持久 agent 步骤边界上执行该策略。 - **`GenerateOptions` 采样只包含 `temperature`/`maxTokens`/`stop`**——没有 `tool_choice`、`top_p` 或 penalty 字段;有产生方落地时词汇才会增长(见[已删除惰性旋钮](../../../.agents/notes/archived/simplification/2026-07-04-drop-inert-request-knobs.md))。 -- **只有出现实际产生方后,相应变体才会加入**——`prefill`、逐工具 `strict`、内容块 `cache` 提示和 `agent` 消息来源变体都没有产生方(见 [Agent Note](../../../.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md))。 +- **变体通常要求实际产生方**——`prefill`、逐工具 `strict`、内容块 `cache` 提示和 `agent` 消息来源变体都没有产生方(见 [Agent Note](../../../.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md))。 - **`BlockAssembler` 只处理核心块类型**——插件添加块类型的流若从未由 `block-end` 关闭,`blocks()` 会抛出异常。 - **`GenerateOptions.sessionId` 是本地声明的品牌类型**——导入 dsh-session 的 `SessionId` 会产生依赖循环。 +- **Session 变更类型是 V4 持久化的例外** — `DeveloperMessage` 承载增量 Session 变更。添加与移除块记录工具名称;所在的 Session 事件将添加绑定到拥有其定义的历史请求头。接纳和恢复规则见 [Session 引用](../../core/session/README.zh.md)。提供方序列化、延迟加载与 UI 展示仍留待后续实现。DeepSeek 两种协议与 pi-ai 均拒绝 developer 历史及 `deferLoading` 请求;Chat 与 Trajectory 拒绝 developer 事件。普通请求的行为不变。 ### 开发备注 diff --git a/packages/llm/llm/src/assembler.ts b/packages/llm/llm/src/assembler.ts index 88ae77d80b..917dd11e2c 100644 --- a/packages/llm/llm/src/assembler.ts +++ b/packages/llm/llm/src/assembler.ts @@ -9,8 +9,8 @@ import { brandString } from '@deepseek-ai/dsh-brand' import { assertNever } from '@deepseek-ai/dsh-util-values' import type { ToolCallId } from './brand.ts' -import { createMessage } from './message.ts' -import type { Message, MessageSource } from './message.ts' +import { createAssistantMessage } from './message.ts' +import type { AssistantMessage, ModelMessageSource } from './message.ts' import type { ContentBlock, FinishReason, ReplayEnvelope, StreamChunk, TokenUsage } from './types.ts' interface PartialBlock { @@ -199,10 +199,10 @@ export class BlockAssembler { /** * The assembled assistant message. - * @param source - producer attribution for the assembled message. + * @param source - provider/model attribution (without the `kind` tag) for the assembled message. * @returns a frozen assistant-role message over `blocks()` (same open-block assembly rules). */ - message(source: MessageSource = { kind: 'plugin', plugin: 'dsh-llm/assembler' }): Message { - return createMessage({ role: 'assistant', content: this.blocks(), source }) + message(source: Omit): AssistantMessage { + return createAssistantMessage({ content: this.blocks(), source }) } } diff --git a/packages/llm/llm/src/content.ts b/packages/llm/llm/src/content.ts index b5c3e59f3d..9d3758b209 100644 --- a/packages/llm/llm/src/content.ts +++ b/packages/llm/llm/src/content.ts @@ -1,6 +1,7 @@ /** Content-block structure helpers. @module @deepseek-ai/dsh-llm/content */ import type { ContentBlock, ImageBlock, LlmImageRequestBudget } from './types.ts' +import type { RequestMessage } from './types.ts' import type { Message } from './message.ts' import type { AttachmentStore, FileAttachmentRef, ImageAttachmentRef, ImageMediaType, RequestImageAttachment, @@ -116,29 +117,25 @@ export function offloadedImageText( } /** - * True when typed model content contains an image block, walking nested - * tool-result content. This is the one recursive image walk shared by every - * image policy (capability gating, text-only serialization, compaction - * survey), so a consumer cannot silently diverge on nesting depth. + * True when typed model content contains an image block. This is the one image + * walk shared by every image policy (capability gating, text-only + * serialization, compaction survey), so a consumer cannot silently diverge. * @param content - typed model content blocks. - * @returns whether any nested block is an image. + * @returns whether any block is an image. */ export function contentHasImage(content: readonly ContentBlock[]): boolean { - return content.some(block => block.type === 'image' - || (block.type === 'tool-result' && contentHasImage(block.content))) + return content.some(block => block.type === 'image') } /** - * True when typed model content contains a file block, walking nested - * tool-result content on the same recursion every file policy shares. + * True when typed model content contains a file block. * Reads current content on every call without retaining scan results. * @param content - typed model content blocks. - * @returns whether any nested block is a file. + * @returns whether any block is a file. */ export function contentHasFile(content: readonly ContentBlock[]): boolean { for (const block of content) { - if (block.type === 'file' - || (block.type === 'tool-result' && contentHasFile(block.content))) return true + if (block.type === 'file') return true } return false } @@ -160,7 +157,7 @@ export function fileHandleText(ref: FileAttachmentRef, readonlyPath: string | un return `[${identity}: verbatim read-only copy saved at ${quoted(readonlyPath)}. Read that path with your file tools when its contents are needed; copy it to a writable location before modifying it. When delegating file work, include this saved path in the delegation prompt; only subagents sharing this execution environment can read it.]` } -/** Replace every file occurrence, including nested tool results, with handle text. */ +/** Replace every file occurrence with handle text. */ function replaceFilesWithHandles( blocks: readonly ContentBlock[], resolvePath: (ref: FileAttachmentRef) => string | undefined, @@ -172,21 +169,13 @@ function replaceFilesWithHandles( next.push({ type: 'text', text: fileHandleText(block.attachment, resolvePath(block.attachment)) }) continue } - if (block.type === 'tool-result') { - const content = replaceFilesWithHandles(block.content, resolvePath) - if (content !== block.content) { - next ??= blocks.slice(0, index) - next.push({ ...block, content }) - continue - } - } next?.push(block) } return next ?? blocks as ContentBlock[] } /** - * Project durable file history into deterministic handle text for every model + * Project request file content into deterministic handle text for every model * route. Unlike images, no provider receives file blocks natively, so this * projection is unconditional in request assembly. * @param messages - complete request history. @@ -196,7 +185,21 @@ function replaceFilesWithHandles( export function projectFilesToText( messages: readonly Message[], resolvePath: (ref: FileAttachmentRef) => string | undefined, -): readonly Message[] { +): readonly Message[] +/** + * Project file content in mixed durable and request-only inputs. + * @param messages - complete request inputs. + * @param resolvePath - resolve a reference's execution-world read path. + * @returns original inputs without files, otherwise copies with handle text. + */ +export function projectFilesToText( + messages: readonly RequestMessage[], + resolvePath: (ref: FileAttachmentRef) => string | undefined, +): readonly RequestMessage[] +export function projectFilesToText( + messages: readonly RequestMessage[], + resolvePath: (ref: FileAttachmentRef) => string | undefined, +): readonly RequestMessage[] { if (!messages.some(message => contentHasFile(message.content))) return messages return messages.map((message) => { const content = replaceFilesWithHandles(message.content, resolvePath) @@ -210,19 +213,17 @@ function base64Length(bytes: number): number { } /** - * Visit every image occurrence of typed content in message order, including - * nested tool-result content. + * Visit every image occurrence of typed content in message order. * @param content - typed model content blocks. * @param visit - called once per occurrence. */ function visitImageBlocks(content: readonly ContentBlock[], visit: (block: ImageBlock) => void): void { for (const block of content) { if (block.type === 'image') visit(block) - else if (block.type === 'tool-result') visitImageBlocks(block.content, visit) } } -/** Replace every offloaded occurrence, including nested tool results, with its placeholder. */ +/** Replace every offloaded occurrence with its placeholder. */ function replaceOffloadedImages( blocks: readonly ContentBlock[], placeholder: (ref: ImageAttachmentRef) => string, @@ -234,14 +235,6 @@ function replaceOffloadedImages( next.push({ type: 'text', text: placeholder(block.attachment) }) continue } - if (block.type === 'tool-result') { - const content = replaceOffloadedImages(block.content, placeholder) - if (content !== block.content) { - next ??= blocks.slice(0, index) - next.push({ ...block, content }) - continue - } - } next?.push(block) } return next ?? blocks as ContentBlock[] @@ -258,7 +251,21 @@ function replaceOffloadedImages( export function projectOffloadedImages( messages: readonly Message[], placeholder: (ref: ImageAttachmentRef) => string, -): readonly Message[] { +): readonly Message[] +/** + * Project offloaded images in mixed durable and request-only inputs. + * @param messages - complete request inputs. + * @param placeholder - replacement text for an offloaded attachment. + * @returns original messages or shallow copies with placeholders. + */ +export function projectOffloadedImages( + messages: readonly RequestMessage[], + placeholder: (ref: ImageAttachmentRef) => string, +): readonly RequestMessage[] +export function projectOffloadedImages( + messages: readonly RequestMessage[], + placeholder: (ref: ImageAttachmentRef) => string, +): readonly RequestMessage[] { return messages.map((message) => { const content = replaceOffloadedImages(message.content, placeholder) return content === message.content ? message : { ...message, content } @@ -309,7 +316,7 @@ function offloadedImagePrefixCount( * @returns how many more leading retained occurrences to offload. */ export function requiredImageOffload( - messages: readonly Message[], + messages: readonly RequestMessage[], budget: Pick, versionBytes: (block: ImageBlock) => number, ): number { @@ -324,7 +331,7 @@ export function requiredImageOffload( return offloadedImagePrefixCount(lengths, budget) } -/** Replace every image occurrence, including nested tool results, for a text-only model. */ +/** Replace every image occurrence for a text-only model. */ function replaceImagesForTextModel(blocks: readonly ContentBlock[]): ContentBlock[] { let next: ContentBlock[] | undefined for (const [index, block] of blocks.entries()) { @@ -333,25 +340,24 @@ function replaceImagesForTextModel(blocks: readonly ContentBlock[]): ContentBloc next.push({ type: 'text', text: textOnlyImageText(block.attachment) }) continue } - if (block.type === 'tool-result') { - const content = replaceImagesForTextModel(block.content) - if (content !== block.content) { - next ??= blocks.slice(0, index) - next.push({ ...block, content }) - continue - } - } next?.push(block) } return next ?? blocks as ContentBlock[] } /** - * Project durable image history into deterministic text for an exact text-only model. + * Project request image content into deterministic text for an exact text-only model. * @param messages - complete request history. * @returns the original list without images, otherwise shallow message copies with stable placeholders. */ -export function projectImagesForTextModel(messages: readonly Message[]): readonly Message[] { +export function projectImagesForTextModel(messages: readonly Message[]): readonly Message[] +/** + * Project image content in mixed durable and request-only inputs for a text-only model. + * @param messages - complete request inputs. + * @returns original inputs without images, otherwise copies with stable placeholders. + */ +export function projectImagesForTextModel(messages: readonly RequestMessage[]): readonly RequestMessage[] +export function projectImagesForTextModel(messages: readonly RequestMessage[]): readonly RequestMessage[] { if (!messages.some(message => contentHasImage(message.content))) return messages return messages.map((message) => { const content = replaceImagesForTextModel(message.content) diff --git a/packages/llm/llm/src/index.ts b/packages/llm/llm/src/index.ts index e17e2011e7..5f633619ff 100644 --- a/packages/llm/llm/src/index.ts +++ b/packages/llm/llm/src/index.ts @@ -11,6 +11,7 @@ import { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typer import { deepFreeze } from '@deepseek-ai/dsh-util-values' import type { GenerateOptions, + RequestMessage, LlmConfigurableProvider, LlmDiscoveredModel, LlmFailure, @@ -24,7 +25,7 @@ import type { StreamChunk, SystemPromptUpdate, } from './types.ts' -import { freezeMessage, type Message } from './message.ts' +import { freezeMessage } from './message.ts' import { resolveRetryPolicy } from './retry-policy.ts' import type { ResolvedRetryPolicy } from './retry-policy.ts' import type { ProviderRequestId } from './brand.ts' @@ -65,8 +66,8 @@ declare module '@deepseek-ai/cordis' { * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen * (mutation throws): its content is a pure function of the session log (the * reconstructability Agent Note), so listeners read it, never rewrite it. - * Hand-built calls do not carry that marker; their messages already obey - * the immutable creation contract. + * Hand-built calls do not carry that marker; callers own their request + * inputs and must keep them unchanged until the stream settles. * @mode waterfall */ 'llm/stream'(this: LlmRuntime, options: GenerateOptions, next: () => AsyncIterable): AsyncIterable @@ -973,9 +974,10 @@ export class LlmRuntime extends TypertRemoteService { /** Remove replay state whose historical route is owned by another adapter. */ private forAdapter(options: GenerateOptions, adapter: LlmAdapter): GenerateOptions { - const messages: Message[] = options.messages.map((message) => { + const messages: RequestMessage[] = options.messages.map((message) => { + if (message.role !== 'assistant') return message const source = message.source - if (message.role !== 'assistant' || source.kind !== 'model' || source.replayState === undefined) return message + if (source.replayState === undefined) return message if (this.adapters.get(source.provider)?.adapter === adapter) return message return freezeMessage({ ...message, @@ -1045,7 +1047,7 @@ export class LlmRuntime extends TypertRemoteService { ? deepFreeze({ ...options, ...resolvedConfig }) : { ...options, ...resolvedConfig } // Files are never dispatched natively: every route receives handle text. - let projectedMessages: readonly Message[] = resolvedOptions.messages + let projectedMessages: readonly RequestMessage[] = resolvedOptions.messages if (projectedMessages.some(message => contentHasFile(message.content))) { projectedMessages = projectFilesToText(projectedMessages, ref => this.fileReadPath(ref)) } @@ -1057,8 +1059,8 @@ export class LlmRuntime extends TypertRemoteService { const projectedOptions = projectedMessages === resolvedOptions.messages ? resolvedOptions : Object.isFrozen(resolvedOptions) - ? deepFreeze({ ...resolvedOptions, messages: projectedMessages as Message[] }) - : { ...resolvedOptions, messages: projectedMessages as Message[] } + ? deepFreeze({ ...resolvedOptions, messages: projectedMessages as RequestMessage[] }) + : { ...resolvedOptions, messages: projectedMessages as RequestMessage[] } const stream = dispatch(this.forAdapter(projectedOptions, adapter)) iterator = stream[Symbol.asyncIterator]() } catch (error: unknown) { diff --git a/packages/llm/llm/src/message.ts b/packages/llm/llm/src/message.ts index 05af6bae3e..d96a63edb6 100644 --- a/packages/llm/llm/src/message.ts +++ b/packages/llm/llm/src/message.ts @@ -4,7 +4,7 @@ import { randomUUID } from '@deepseek-ai/dsh-util-crypto' import { brandString } from '@deepseek-ai/dsh-brand' import { deepFreeze } from '@deepseek-ai/dsh-util-values' import type { MessageId, ToolCallId } from './brand.ts' -import type { ContentBlock, ToolResultBlock } from './types.ts' +import type { ContentBlock } from './types.ts' /** Provider/model identity and adapter-private replay data for an assistant message. */ export interface AssistantProviderMetadata { @@ -25,12 +25,17 @@ export interface ModelMessageSource extends AssistantProviderMetadata { kind: 'model' } -/** Required source of a user-role message carrying one tool result. */ +/** Required source of a tool-role message carrying one tool result. */ export interface ToolMessageSource { kind: 'tool' callId: ToolCallId } +/** Required source of a system-role message produced by the system-prompt plugin. */ +export interface SystemPromptMessageSource { + kind: 'system-prompt' +} + /** * The kind of information in producer-supplied context, declared by the * producer in the same `MessageSource`. @@ -96,20 +101,23 @@ export type ContextFormed = | { readonly form: 'recall' } /** - * Where a message (or injected content) came from. - * Merge-extensible sum type — plugins add their own `kind`s. + * Where a message (or injected content) came from, in the harness's own + * vocabulary. Merge-extensible sum type — each producer declares its own + * `kind` in its own module; there is no shared catch-all `plugin` kind. + * Model and tool sources answer their role messages; user messages carry any + * producer's kind, and consumers fall through unknown kinds. */ export interface MessageSourceMap { user: { kind: 'user' } - plugin: { kind: 'plugin'; plugin: string } & ContextFormed model: ModelMessageSource tool: ToolMessageSource + 'system-prompt': SystemPromptMessageSource } /** - * Bound for a `notice` summary. The account rides a collapsed transcript row - * and is committed to the durable log, while its inputs — task labels, goal - * objectives, tool arguments — are caller text with no length of their own. + * Bound for a `notice` summary. Producers commit the one-line account to the + * durable log; its inputs — task labels, goal objectives, tool arguments — + * are caller text with no length of their own. */ export const CONTEXT_SUMMARY_MAX_CHARS = 120 @@ -127,47 +135,70 @@ export function boundContextSummary(summary: string): string { /** Any known message source, derived from {@link MessageSourceMap}; switch on `kind` and fall through unknowns (merge-extensible). */ export type MessageSource = MessageSourceMap[keyof MessageSourceMap] -/** One immutable message representation shared by delivery, durable history, and model requests. */ -export interface Message { +/** Shared immutable fields of every conversation message. */ +interface MessageBase { /** Stable identity preserved across every representation boundary. */ readonly id: MessageId - /** Provider-neutral conversation role. */ - readonly role: 'system' | 'user' | 'assistant' /** Exact model-facing blocks. */ - readonly content: ContentBlock[] - /** Required source fields supplied by the producer. */ + readonly content: readonly ContentBlock[] + /** Required source fields supplied by the producer. + * @persistenceSource user developer + */ readonly source: MessageSource } -/** A user-role specialization of the one shared message representation. */ -export interface UserMessage extends Message { +/** A rendered system prompt attributed to the system-prompt producer; empty content sends no prompt. */ +export interface SystemMessage extends MessageBase { + readonly role: 'system' + readonly source: MessageSourceMap['system-prompt'] +} + +/** Incremental agent session changes in conversation order, currently tool additions and removals. */ +export interface DeveloperMessage extends MessageBase { + readonly role: 'developer' +} + +/** A user-role specialization of the shared message representation. */ +export interface UserMessage extends MessageBase { readonly role: 'user' } /** A model-produced assistant specialization of the shared message representation. */ -export interface AssistantMessage extends Message { +export interface AssistantMessage extends MessageBase { readonly role: 'assistant' readonly source: ModelMessageSource } -/** - * A system-role specialization of the shared message representation: one - * rendered system prompt attributed to the plugin that assembled it. Empty - * `content` means "no system prompt" and projects to no wire message. - */ -export interface SystemMessage extends Message { - readonly role: 'system' - readonly source: MessageSourceMap['plugin'] -} - -/** A tool-result specialization whose model-facing block retains call correlation. */ -export interface ToolResultMessage extends Message { - readonly role: 'user' - readonly content: [ToolResultBlock] +/** A first-class tool-role message carrying the result of one tool invocation. */ +export interface ToolResultMessage extends MessageBase { + readonly role: 'tool' readonly source: ToolMessageSource + /** Provider-issued id of the tool call this message answers. */ + readonly toolCallId: ToolCallId + /** Whether the tool invocation failed. */ + readonly isError?: boolean } -type NewMessage = Omit +/** + * The conversation messages persisted by Session, keyed by role. This map is + * closed because every model-visible role must have a durable Session event + * and an adapter projection. + */ +export interface MessageRoleMap { + system: SystemMessage + developer: DeveloperMessage + user: UserMessage + assistant: AssistantMessage + tool: ToolResultMessage +} + +/** Any persisted conversation message, discriminated by its `role`. */ +export type Message = MessageRoleMap[keyof MessageRoleMap] + +type NewMessage = { + [Role in keyof MessageRoleMap]: Omit +}[keyof MessageRoleMap] +type NewDeveloperMessage = Omit type NewUserMessage = Omit type NewAssistantMessage = Omit & { readonly source: Omit & { readonly kind?: never } @@ -190,10 +221,21 @@ export function freezeMessage(message: T): T { export function createMessage( input: T & { readonly id?: never }, ): T & Pick { - return freezeMessage({ + return deepFreeze(structuredClone({ ...input, id: brandString(randomUUID()), - }) + })) +} + +/** + * Create an identified, immutable developer message. + * @param input - content and producer source for the new message. + * @returns a detached developer message with a fresh identity. + */ +export function createDeveloperMessage( + input: T & { readonly id?: never; readonly role?: never }, +): T & Pick { + return createMessage({ ...input, role: 'developer' }) } /** @@ -232,37 +274,34 @@ export function createAssistantMessage( * Create and freeze one identified system-role message holding a rendered * system prompt. * @param text - the complete rendered prompt; `''` records "no system prompt". - * @param plugin - the plugin that assembled the prompt. * @returns an immutable system message with a fresh stable identity. */ -export function createSystemMessage(text: string, plugin: string): SystemMessage { +export function createSystemMessage(text: string): SystemMessage { return createMessage({ role: 'system', content: text.length === 0 ? [] : [{ type: 'text', text }], - source: { kind: 'plugin', plugin }, + source: { kind: 'system-prompt' }, }) } /** Input whose acceptance creates one tool-result message. */ export interface ToolResultMessageInput { readonly callId: ToolCallId - readonly content: ContentBlock[] + readonly content: readonly ContentBlock[] readonly isError: boolean } /** * Create and freeze one identified tool-result message. * @param input - call identity, raw result blocks, and outcome. - * @returns an immutable user-role tool-result message. + * @returns an immutable tool-role message that answers the tool call. */ export function createToolResultMessage(input: ToolResultMessageInput): ToolResultMessage { - return createUserMessage({ + return createMessage({ + role: 'tool', source: { kind: 'tool', callId: input.callId }, - content: [{ - type: 'tool-result', - toolCallId: input.callId, - content: input.content, - isError: input.isError, - }], + toolCallId: input.callId, + content: input.content, + isError: input.isError, }) } diff --git a/packages/llm/llm/src/types.ts b/packages/llm/llm/src/types.ts index d77aa7f042..dcd66d2868 100644 --- a/packages/llm/llm/src/types.ts +++ b/packages/llm/llm/src/types.ts @@ -7,7 +7,7 @@ import type { Branded } from '@deepseek-ai/dsh-brand' import type { FileAttachmentRef, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment' import type { ToolCallId, ProviderRequestId, ReasoningEffortId } from './brand.ts' -import type { Message } from './message.ts' +import type { Message, UserMessage } from './message.ts' declare module '@deepseek-ai/cordis' { interface Events { @@ -26,6 +26,7 @@ declare module '@deepseek-ai/cordis' { export type { AssistantMessage, + DeveloperMessage, AssistantProviderMetadata, Message, MessageSource, @@ -110,17 +111,29 @@ export interface ToolCallBlock { arguments: string } -/** The result of a tool invocation, sent back to the model. */ -export interface ToolResultBlock { - type: 'tool-result' - toolCallId: ToolCallId - content: ContentBlock[] - isError?: boolean +/** Activates a tool definition from the developer event's referenced request header. */ +export interface ToolAdditionBlock { + type: 'tool-addition' + /** Name of exactly one tool in the referenced historical header. */ + toolName: string + /** + * Reserved against inline definitions; the historical request header owns the schema. + * @persistenceReserved + */ + tool?: never +} + +/** Records the dynamic removal of a tool identified by its session-local name. */ +export interface ToolRemovalBlock { + type: 'tool-removal' + toolName: string } /** * Merge-extensible content blocks keyed by `type`. New core blocks must land - * with adapter, UI, and compaction support. + * with adapter, UI, and compaction support. Developer tool-change blocks are + * reserved for Session V4 persistence; providers and UI reject them until + * their producers and consumers are implemented together. */ export interface ContentBlockMap { 'text': TextBlock @@ -128,7 +141,8 @@ export interface ContentBlockMap { 'image': ImageBlock 'file': FileBlock 'tool-call': ToolCallBlock - 'tool-result': ToolResultBlock + 'tool-addition': ToolAdditionBlock + 'tool-removal': ToolRemovalBlock } /** The block `type` tag vocabulary; widens as plugins add entries to {@link ContentBlockMap}. */ @@ -445,12 +459,29 @@ export type StreamChunk = * it from this package. */ export interface ToolSchema { + /** + * Requests deferred loading of the tool definition into model context, + * independently of whether a tool-addition block records the tool. + * Uses Anthropic's defer_loading terminology. + */ + deferLoading?: true name: string description: string /** JSON Schema object for the arguments. */ parameters: Record } +/** User input for one LLM request; it has no durable Session identity or source. */ +export interface RequestUserInput { + readonly role: 'user' + readonly content: UserMessage['content'] + readonly id?: never + readonly source?: never +} + +/** A durable conversation message or a user input used only for one request. */ +export type RequestMessage = Message | RequestUserInput + /** A single model request, fully assembled. */ export interface GenerateOptions { /** Registered provider route selecting the adapter instance. */ @@ -462,9 +493,9 @@ export interface GenerateOptions { * Ordered conversation messages, exactly as the provider sees them. A * loop-built request passes the derived history (dsh-agent-loop), whose * leading system-role message carries the system prompt; a hand-built - * one-shot passes any list. + * one-shot may include identity-free user inputs. */ - messages: Message[] + messages: RequestMessage[] /** * System prompt text for one-shot callers; adapters map it to the provider's * system slot ahead of `messages`. Loop-built requests leave it undefined. diff --git a/packages/llm/llm/tests/assembler.spec.ts b/packages/llm/llm/tests/assembler.spec.ts index 2cbfc07f63..dc6b14422c 100644 --- a/packages/llm/llm/tests/assembler.spec.ts +++ b/packages/llm/llm/tests/assembler.spec.ts @@ -26,7 +26,7 @@ describe('BlockAssembler', () => { ]) expect(assembler.usage).toEqual({ inputTokens: 10, outputTokens: 5 }) expect(assembler.finish).toEqual({ kind: 'tool-calls' }) - expect(assembler.message().role).toBe('assistant') + expect(assembler.message({ provider: 'mock', model: 'mock' }).role).toBe('assistant') }) it('records the completed block from block-end', () => { diff --git a/packages/llm/llm/tests/content.spec.ts b/packages/llm/llm/tests/content.spec.ts index 61821d8f9a..8e00ecfb44 100644 --- a/packages/llm/llm/tests/content.spec.ts +++ b/packages/llm/llm/tests/content.spec.ts @@ -4,6 +4,7 @@ import type { AttachmentStore, ImageMediaType } from '@deepseek-ai/dsh-attachmen import { ToolCallId, contentHasFile, + createToolResultMessage, createUserMessage, fileHandleText, projectFilesToText, @@ -14,9 +15,9 @@ import { resolveImageAttachmentAccess, requestImageHandleText, } from '../src/index.ts' -import type { ContentBlock } from '../src/index.ts' +import type { ContentBlock, RequestUserInput } from '../src/index.ts' -const source = { kind: 'plugin' as const, plugin: 'test' } +const source = { kind: 'test' as const } const OMITTED = '[omitted]' @@ -35,71 +36,73 @@ function image(bytes: number, offloaded?: true): Extract { - it('visits image occurrences at every tool-result depth in message order', () => { + it('visits image occurrences in user and tool messages in message order', () => { const seen: number[] = [] - const content: ContentBlock[] = [ - { type: 'text', text: 'before' }, - image(1), - { - type: 'tool-result', - toolCallId: ToolCallId('shot'), - content: [ - { type: 'text', text: 'x' }, - image(2), - { - type: 'tool-result', - toolCallId: ToolCallId('nested'), - content: [{ type: 'tool-result', toolCallId: ToolCallId('deep'), content: [image(4)] }], - }, - ], - }, - image(3), + const messages = [ + createUserMessage({ content: [{ type: 'text', text: 'before' }, image(1)], source }), + createToolResultMessage({ + callId: ToolCallId('shot'), + content: [{ type: 'text', text: 'x' }, image(2)], + isError: false, + }), + createToolResultMessage({ + callId: ToolCallId('second'), + content: [image(4)], + isError: false, + }), + createUserMessage({ content: [image(3)], source }), ] - expect(requiredImageOffload([createUserMessage({ content, source })], - { representation: 'raw', maxImages: 0 }, (block) => { - seen.push(block.attachment.bytes) - return block.attachment.bytes - })).toBe(4) + expect(requiredImageOffload(messages, { representation: 'raw', maxImages: 0 }, (block) => { + seen.push(block.attachment.bytes) + return block.attachment.bytes + })).toBe(4) expect(seen).toEqual([1, 2, 4, 3]) }) }) describe('projectOffloadedImages', () => { + it('keeps request-only inputs identity-free when replacing image content', () => { + const input: RequestUserInput = { role: 'user', content: [image(3, true)] } + expect(projectOffloadedImages([input], () => OMITTED)).toEqual([ + { role: 'user', content: [{ type: 'text', text: OMITTED }] }, + ]) + expect(projectImagesForTextModel([input])).toEqual([ + { role: 'user', content: [{ type: 'text', text: '[image omitted because this model accepts text only; attachment sha256:aaaaaaaa]' }] }, + ]) + expect(input.content).toEqual([image(3, true)]) + }) + it('keeps messages without offloaded occurrences by identity', () => { const messages = [createUserMessage({ content: [image(300)], source })] const projected = projectOffloadedImages(messages, () => OMITTED) expect(projected[0]).toBe(messages[0]) }) - it('replaces marked top-level and nested occurrences with route placeholders', () => { + it('replaces marked user and tool occurrences with route placeholders', () => { const messages = [ - createUserMessage({ - content: [{ type: 'tool-result', toolCallId: ToolCallId('shot'), content: [image(3, true)] }], - source, + createToolResultMessage({ + callId: ToolCallId('shot'), + content: [image(3, true)], + isError: false, }), createUserMessage({ content: [image(3, true), image(3)], source }), ] const projected = projectOffloadedImages(messages, ref => `${OMITTED}:${ref.bytes}`) - expect(projected[0]?.content).toEqual([{ - type: 'tool-result', - toolCallId: ToolCallId('shot'), - content: [{ type: 'text', text: `${OMITTED}:3` }], - }]) + expect(projected[0]?.content).toEqual([{ type: 'text', text: `${OMITTED}:3` }]) expect(projected[1]?.content).toEqual([{ type: 'text', text: `${OMITTED}:3` }, image(3)]) expect(messages[1]?.content[0]).toEqual(image(3, true)) }) - it('keeps unchanged nested content while replacing a later occurrence', () => { - const nested = { - type: 'tool-result' as const, - toolCallId: ToolCallId('text-only'), - content: [{ type: 'text' as const, text: 'kept' }], - } - const messages = [createUserMessage({ content: [nested, image(3, true)], source })] - expect(projectOffloadedImages(messages, () => OMITTED)[0]?.content).toEqual([ - nested, - { type: 'text', text: OMITTED }, - ]) + it('keeps unchanged tool content while replacing a later image', () => { + const unchanged = createToolResultMessage({ + callId: ToolCallId('text-only'), + content: [{ type: 'text', text: 'kept' }], + isError: false, + }) + const messages = [unchanged, createUserMessage({ content: [image(3, true)], source })] + const projected = projectOffloadedImages(messages, () => OMITTED) + expect(projected[0]).toBe(unchanged) + expect(projected[1]?.content).toEqual([{ type: 'text', text: OMITTED }]) }) }) @@ -265,44 +268,46 @@ describe('projectImagesForTextModel', () => { it('returns image-free history unchanged', () => { const messages = [createUserMessage({ content: [{ type: 'text', text: 'plain' }], source })] expect(projectImagesForTextModel(messages)).toBe(messages) - const nested = [createUserMessage({ - content: [{ type: 'tool-result', toolCallId: ToolCallId('plain-result'), content: messages[0]!.content }], - source, + const results = [createToolResultMessage({ + callId: ToolCallId('plain-result'), + content: messages[0]!.content, + isError: false, })] - expect(projectImagesForTextModel(nested)).toBe(nested) + expect(projectImagesForTextModel(results)).toBe(results) }) - it('replaces direct and nested images while retaining unaffected messages and blocks', () => { + it('replaces direct images while retaining unaffected messages', () => { const plain = createUserMessage({ content: [{ type: 'text', text: 'plain' }], source }) - const nested = { - type: 'tool-result' as const, - toolCallId: ToolCallId('nested-image'), - content: [{ type: 'text' as const, text: 'before' }, image(3), { type: 'text' as const, text: 'after' }], - } - const unchangedNested = { - type: 'tool-result' as const, - toolCallId: ToolCallId('text-only'), - content: [{ type: 'text' as const, text: 'unchanged' }], - } + const unchangedTool = createToolResultMessage({ + callId: ToolCallId('text-only'), + content: [{ type: 'text', text: 'unchanged' }], + isError: false, + }) const visual = createUserMessage({ - content: [{ type: 'text', text: 'lead' }, image(3), unchangedNested, nested], + content: [{ type: 'text', text: 'lead' }, image(3)], source, }) + const visualTool = createToolResultMessage({ + callId: ToolCallId('nested-image'), + content: [ + { type: 'text', text: 'before' }, + image(3), + { type: 'text', text: 'after' }, + ], + isError: false, + }) - const projected = projectImagesForTextModel([plain, visual]) + const projected = projectImagesForTextModel([plain, visual, unchangedTool, visualTool]) expect(projected[0]).toBe(plain) expect(projected[1]?.content).toEqual([ { type: 'text', text: 'lead' }, { type: 'text', text: '[image omitted because this model accepts text only; attachment sha256:aaaaaaaa]' }, - unchangedNested, - { - ...nested, - content: [ - { type: 'text', text: 'before' }, - { type: 'text', text: '[image omitted because this model accepts text only; attachment sha256:aaaaaaaa]' }, - { type: 'text', text: 'after' }, - ], - }, + ]) + expect(projected[2]).toBe(unchangedTool) + expect(projected[3]?.content).toEqual([ + { type: 'text', text: 'before' }, + { type: 'text', text: '[image omitted because this model accepts text only; attachment sha256:aaaaaaaa]' }, + { type: 'text', text: 'after' }, ]) }) }) @@ -319,41 +324,32 @@ describe('file projection', () => { } } - it('detects file blocks at the top level and inside nested tool results', () => { - expect(contentHasFile([{ type: 'text', text: 'x' }])).toBe(false) - expect(contentHasFile([fileBlock('a.txt')])).toBe(true) - expect(contentHasFile([{ - type: 'tool-result', - toolCallId: ToolCallId('call-1'), - content: [{ - type: 'tool-result', - toolCallId: ToolCallId('call-2'), - content: [fileBlock('deep.txt')], - }], - }])).toBe(true) + it('keeps request-only inputs identity-free when replacing file content', () => { + const block = fileBlock('review.txt') + const input: RequestUserInput = { role: 'user', content: [block] } + expect(projectFilesToText([input], () => '/copies/review.txt')).toEqual([ + { role: 'user', content: [{ type: 'text', text: fileHandleText(block.attachment, '/copies/review.txt') }] }, + ]) + expect(input.content).toEqual([block]) }) - it('scans frozen branches and observes later mutations in file-free content', () => { - const nested: ContentBlock[] = [{ type: 'text', text: 'plain' }] - const empty: ContentBlock[] = [] - Object.freeze(empty) - const content: ContentBlock[] = [ - { type: 'tool-result', toolCallId: ToolCallId('empty'), content: empty }, - { type: 'tool-result', toolCallId: ToolCallId('nested'), content: nested }, - ] + it('detects file blocks anywhere in message content', () => { + expect(contentHasFile([{ type: 'text', text: 'x' }])).toBe(false) + expect(contentHasFile([fileBlock('a.txt')])).toBe(true) + }) + + it('scans frozen blocks and observes later mutations in file-free content', () => { + const content: ContentBlock[] = [{ type: 'text', text: 'plain' }] Object.freeze(content[0]) - Object.freeze(content[1]) - Object.freeze(content) expect(contentHasFile(Object.freeze([]))).toBe(false) expect(contentHasFile(content)).toBe(false) - nested.push(fileBlock('later.txt')) + content.push(fileBlock('later.txt')) expect(contentHasFile(content)).toBe(true) - nested.pop() + content.pop() expect(contentHasFile(content)).toBe(false) - nested.push(fileBlock('frozen.txt')) - Object.freeze(nested[0]) - Object.freeze(nested[1]) - Object.freeze(nested) + content.push(fileBlock('frozen.txt')) + Object.freeze(content[1]) + Object.freeze(content) expect(contentHasFile(content)).toBe(true) }) @@ -373,37 +369,33 @@ describe('file projection', () => { it('replaces every file occurrence with handle text and keeps file-free history identical', () => { const plain = [createUserMessage({ content: [{ type: 'text', text: 'hi' }], source })] expect(projectFilesToText(plain, () => '/p')).toBe(plain) - const unchangedTool = { - type: 'tool-result' as const, - toolCallId: ToolCallId('call-plain'), - content: [{ type: 'text' as const, text: 'unchanged result' }], - } - const messages = [plain[0]!, createUserMessage({ - content: [ - fileBlock('top.csv'), - { type: 'text', text: 'keep' }, - unchangedTool, - { - type: 'tool-result', - toolCallId: ToolCallId('call-3'), - content: [fileBlock('nested.csv')], - }, - ], - source, - })] + const messages = [ + plain[0]!, + createUserMessage({ + content: [ + fileBlock('top.csv'), + { type: 'text', text: 'keep' }, + ], + source, + }), + createToolResultMessage({ + callId: ToolCallId('call-3'), + content: [fileBlock('nested.csv')], + isError: false, + }), + ] const projected = projectFilesToText(messages, ref => `/copies/${ref.name}`) expect(projected).not.toBe(messages) expect(projected[0]).toBe(messages[0]) const content = projected[1]!.content expect(content[0]).toEqual({ type: 'text', text: fileHandleText(fileBlock('top.csv').attachment, '/copies/top.csv') }) expect(content[1]).toEqual({ type: 'text', text: 'keep' }) - expect(content[2]).toBe(messages[1]!.content[2]) - const nested = content[3] as Extract - expect(nested.content[0]).toEqual({ + expect(projected[2]!.content[0]).toEqual({ type: 'text', text: fileHandleText(fileBlock('nested.csv').attachment, '/copies/nested.csv'), }) // The durable message is untouched: projection returns shallow copies. expect(messages[1]!.content[0]!.type).toBe('file') + expect(messages[2]!.content[0]!.type).toBe('file') }) }) diff --git a/packages/llm/llm/tests/message.spec.ts b/packages/llm/llm/tests/message.spec.ts index 3d458611d2..1f05272fba 100644 --- a/packages/llm/llm/tests/message.spec.ts +++ b/packages/llm/llm/tests/message.spec.ts @@ -1,7 +1,11 @@ -import { describe, expect, it } from 'vitest' +import { describe, expect, expectTypeOf, it } from 'vitest' import { ToolCallId, + boundContextSummary, + CONTEXT_SUMMARY_MAX_CHARS, createAssistantMessage, + createDeveloperMessage, + createSystemMessage, createToolResultMessage, createUserMessage, freezeMessage, @@ -9,10 +13,38 @@ import { } from '@deepseek-ai/dsh-llm' describe('message construction', () => { + it('detaches and freezes developer tool names without copying their definitions', () => { + const content = [{ type: 'tool-addition' as const, toolName: 'search' }] + const message = createDeveloperMessage({ content, source: { kind: 'test' } }) + content[0]!.toolName = 'changed' + expect(message.role).toBe('developer') + expect(message.content).toEqual([{ type: 'tool-addition', toolName: 'search' }]) + expect(Object.isFrozen(message.content[0])).toBe(true) + expect(freezeMessage(message).id).toBe(message.id) + }) + + it('bounds producer summaries while preserving summaries at the exact limit', () => { + const exact = 'x'.repeat(CONTEXT_SUMMARY_MAX_CHARS) + expect(boundContextSummary(exact)).toBe(exact) + expect(boundContextSummary(exact + 'x')).toBe(exact.slice(0, -1) + '…') + }) + + it('preserves system-prompt attribution on immutable system messages', () => { + const expectedSource: { kind: 'system-prompt' } = { kind: 'system-prompt' } + const message = createSystemMessage('rule') + expectTypeOf(message.source).toEqualTypeOf(expectedSource) + expect(message.role).toBe('system') + expect(message.content).toEqual([{ type: 'text', text: 'rule' }]) + expect(message.source).toEqual(expectedSource) + expect(Object.isFrozen(message)).toBe(true) + expect(Object.isFrozen(message.source)).toBe(true) + expect(createSystemMessage('').content).toEqual([]) + }) + it('assigns identity immediately and returns a detached deep-frozen message', () => { const input = { content: [{ type: 'text' as const, text: 'original' }], - source: { kind: 'plugin' as const, plugin: 'test' }, + source: { kind: 'test' as const }, } const message = createUserMessage(input) @@ -83,14 +115,11 @@ describe('message construction', () => { }) expect(message).toMatchObject({ - role: 'user', + role: 'tool', + toolCallId: callId, + isError: false, source: { kind: 'tool', callId }, - content: [{ - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text: 'result' }], - isError: false, - }], + content: [{ type: 'text', text: 'result' }], }) expect(message.id).not.toHaveLength(0) expect(Object.isFrozen(message)).toBe(true) diff --git a/packages/llm/llm/tests/properties.spec.ts b/packages/llm/llm/tests/properties.spec.ts index 22f854b378..a6752adc65 100644 --- a/packages/llm/llm/tests/properties.spec.ts +++ b/packages/llm/llm/tests/properties.spec.ts @@ -76,7 +76,7 @@ describe('BlockAssembler properties', () => { const a = feed(chunks) expect(a.blocks()).toEqual(a.blocks()) // And message().content mirrors blocks(). - expect(a.message().content).toEqual(a.blocks()) + expect(a.message({ provider: 'mock', model: 'mock' }).content).toEqual(a.blocks()) })) }) diff --git a/packages/llm/llm/tests/service.spec.ts b/packages/llm/llm/tests/service.spec.ts index 74265c6510..11011c5018 100644 --- a/packages/llm/llm/tests/service.spec.ts +++ b/packages/llm/llm/tests/service.spec.ts @@ -25,6 +25,13 @@ import type { SystemPromptUpdate, } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + class ScriptedAdapter extends LlmAdapter { constructor(private script: StreamChunk[]) { super() @@ -1056,7 +1063,7 @@ describe('LlmRuntime', () => { model: 'text-only', messages: [createUserMessage({ content: [{ type: 'image', attachment }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, })], })) @@ -1071,7 +1078,7 @@ describe('LlmRuntime', () => { model: 'text-only', messages: [createUserMessage({ content: [{ type: 'image', attachment }], - source: { kind: 'plugin' as const, plugin: 'test' }, + source: { kind: 'test' as const }, })], }) await collect(ctx.llm.stream(frozen)) @@ -1229,6 +1236,29 @@ describe('LlmRuntime', () => { expect(adapter.lastOptions?.provider).toBe('routed') }) + it('dispatches identity-free user input beside durable assistant history', async () => { + const ctx = new Context() + await ctx.plugin(LlmRuntime) + ctx.llm.registerAdapter(['historical'], new RecordingAdapter(SCRIPT)) + const target = new RecordingAdapter(SCRIPT) + ctx.llm.registerAdapter(['target'], target) + const input = { role: 'user' as const, content: [{ type: 'text' as const, text: 'summarize' }] } + const assistant = createMessage({ + role: 'assistant', + content: [{ type: 'text', text: 'old response' }], + source: { kind: 'model', provider: 'historical', model: 'old-model', replayState: { private: 'state' } }, + }) + for await (const _chunk of ctx.llm.stream({ + provider: 'target', model: 'new-model', messages: [assistant, input], + })) { /* drain */ } + expect(target.lastOptions?.messages[1]).toBe(input) + expect(target.lastOptions?.messages[1]).toEqual({ role: 'user', content: [{ type: 'text', text: 'summarize' }] }) + expect(target.lastOptions?.messages[0]).toEqual({ + ...assistant, source: { kind: 'model', provider: 'historical', model: 'old-model' }, + }) + expect(assistant.source.replayState).toEqual({ private: 'state' }) + }) + it('keeps replay state when historical and target providers belong to the same adapter instance', async () => { const ctx = new Context() await ctx.plugin(LlmRuntime) diff --git a/packages/llm/token-meter/src/estimate.ts b/packages/llm/token-meter/src/estimate.ts index 99ebbb2aaf..ca54abf6b2 100644 --- a/packages/llm/token-meter/src/estimate.ts +++ b/packages/llm/token-meter/src/estimate.ts @@ -52,9 +52,6 @@ export function estimateContent(blocks: readonly ContentBlock[]): number { + Math.ceil(block.arguments.length / CHARS_PER_TOKEN) + BLOCK_OVERHEAD break - case 'tool-result': - tokens += estimateContent(block.content) + BLOCK_OVERHEAD - break default: // ContentBlockMap is merge-extensible; unknown blocks (and image // references, whose request price is route-owned) retain a diff --git a/packages/llm/token-meter/src/surface-fold.ts b/packages/llm/token-meter/src/surface-fold.ts index 7cea95adb0..29df77f87a 100644 --- a/packages/llm/token-meter/src/surface-fold.ts +++ b/packages/llm/token-meter/src/surface-fold.ts @@ -64,10 +64,6 @@ function collectProjectedAttachments( } else if (block.type === 'file') { files.push(block.attachment) fileTokens += estimateStructuralBlock(block) - } else if (block.type === 'tool-result') { - const nested = collectProjectedAttachments(block.content, images, files) - imageTokens += nested.imageTokens - fileTokens += nested.fileTokens } } return { imageTokens, fileTokens } diff --git a/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts b/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts index 3c7081a9b2..d6fee3cb04 100644 --- a/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts +++ b/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts @@ -5,6 +5,7 @@ import { afterEach, describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createMessage, createSystemMessage, createUserMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, ToolSchema } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionSeq as SessionSeqType } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' @@ -19,6 +20,12 @@ import { estimateToolsTokens, } from '../src/estimate.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const contexts: Context[] = [] afterEach(async () => { await Promise.all(contexts.splice(0).map(ctx => ctx.fiber.dispose())) @@ -32,6 +39,8 @@ const TOOLS: ToolSchema[] = [{ parameters: { type: 'object', properties: {} }, }] +const SYSTEM_SOURCE = { kind: 'system-prompt' } as const + async function harness(): Promise<{ ctx: Context; session: Session }> { const ctx = new Context() contexts.push(ctx) @@ -54,14 +63,12 @@ function appendUser(session: Session, text: string): SessionSeqType { }), { surfaceOp: 'append' }).seq } -const SYSTEM_PLUGIN = '@deepseek-ai/dsh-system-prompt' - /** Append the rendered system prompt as surface node 0, the way the loop does before the first user message. */ function appendSystem(session: Session, text: string): SessionSeqType { return session.append('system/message', { turn: 1, step: 1, - message: createSystemMessage(text, SYSTEM_PLUGIN), + message: createSystemMessage(text), }, { surfaceOp: 'append' }).seq } @@ -70,7 +77,7 @@ function replaceSystem(session: Session, node: SessionSeqType, text: string): Se return session.append('system/message', { turn: 1, step: 1, - message: createSystemMessage(text, SYSTEM_PLUGIN), + message: createSystemMessage(text), }, { surfaceOp: { op: 'replace', startSeq: node, endSeq: node }, sourceEventSeqs: [node] }).seq } @@ -179,7 +186,7 @@ describe('contextBreakdown session projection', () => { appendSummaryMeter(ctx, session, question, followUp) const summary = createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) session.append('user/message', summary, { surfaceOp: { op: 'replace', startSeq: question, endSeq: followUp }, @@ -231,7 +238,7 @@ describe('contextBreakdown session projection', () => { const second = appendUser(session, 'and a second entry') const summary = createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }) appendSummaryMeter(ctx, session, first, second) session.append('user/message', summary, { @@ -279,7 +286,7 @@ describe('contextBreakdown session projection', () => { expect(agree()).toBe(grown) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: question, endSeq: answer }, sourceEventSeqs: [question, answer], @@ -313,7 +320,7 @@ describe('contextBreakdown session projection', () => { head = replaceSystem(session, head, 'head rewritten at a newer event seq') const agree = (text: string): void => { const view = projected(ctx, session) - expect(view.systemTokens).toBe(estimateSystemMessage(createSystemMessage(text, SYSTEM_PLUGIN))) + expect(view.systemTokens).toBe(estimateSystemMessage(createSystemMessage(text))) expect(view.messageTokens).toBeGreaterThanOrEqual(0) expect(view.systemTokens + view.messageTokens) .toBe(ctx.tokenMeter.measure(session).nodes.reduce((total, node) => total + node.heuristicTokens, 0)) @@ -372,7 +379,7 @@ describe('contextBreakdown session projection', () => { expect(Object.keys(state().nodes[0]!).sort()).toEqual(['heuristicTokens', 'seq', 'system']) const shadowed = [...session.surface.nodes] session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'summary' }], source: { kind: 'user' }, + content: [{ type: 'text', text: 'summary' }], source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: first, endSeq: last }, sourceEventSeqs: shadowed }) expect(state().nodes).toHaveLength(1) expect(projected(ctx, session).messageTokens).toBe(10) @@ -494,25 +501,22 @@ describe('shared estimator', () => { expect(estimateContent([{ type: 'text', text: 'abcd' }])).toBe(5) expect(estimateContent([{ type: 'reasoning', text: 'abcdefgh' }] as ContentBlock[])).toBe(6) expect(estimateContent([{ type: 'tool-call', id: 'c' as never, name: 'bash', arguments: '{"a":1}' }])).toBe(7) - expect(estimateContent([{ - type: 'tool-result', toolCallId: 'c' as never, - content: [{ type: 'text', text: 'abcd' }], - }])).toBe(9) + expect(estimateContent([{ type: 'text', text: 'abcd' }])).toBe(5) const unknown = { type: 'mystery', payload: 'abc' } as unknown as ContentBlock expect(estimateContent([unknown])).toBe(4 + Math.ceil(JSON.stringify(unknown).length / 4)) }) it('prices the system node without block overhead and an empty prompt to zero', () => { - expect(estimateSystemMessage(createSystemMessage('', SYSTEM_PLUGIN))).toBe(0) - expect(estimateSystemMessage(createSystemMessage('abcdefgh', SYSTEM_PLUGIN))).toBe(6) + expect(estimateSystemMessage(createSystemMessage(''))).toBe(0) + expect(estimateSystemMessage(createSystemMessage('abcdefgh'))).toBe(6) // estimateMessage routes the system role to the same figure. - expect(estimateMessage(createSystemMessage('abcdefgh', SYSTEM_PLUGIN))).toBe(6) + expect(estimateMessage(createSystemMessage('abcdefgh'))).toBe(6) // A non-text block in a system message keeps a conservative JSON price. const image = { type: 'image', attachment: { attachmentId: 'a' } } as unknown as ContentBlock expect(estimateSystemMessage(createMessage({ role: 'system', content: [{ type: 'text', text: 'abcd' }, image], - source: { kind: 'plugin', plugin: SYSTEM_PLUGIN }, + source: SYSTEM_SOURCE, }))).toBe(Math.ceil((4 + JSON.stringify(image).length) / 4) + 4) }) diff --git a/packages/llm/token-meter/tests/route-pricing.spec.ts b/packages/llm/token-meter/tests/route-pricing.spec.ts index 360d1b6352..bf11f1b039 100644 --- a/packages/llm/token-meter/tests/route-pricing.spec.ts +++ b/packages/llm/token-meter/tests/route-pricing.spec.ts @@ -2,7 +2,7 @@ import { imageOffloadProjection } from '@deepseek-ai/dsh-compaction-image-offloa import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { - LlmRuntime, LlmAdapter, createMessage, createUserMessage, projectFilesToText, + LlmRuntime, LlmAdapter, createMessage, createToolResultMessage, createUserMessage, projectFilesToText, ToolCallId, } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, LlmImageRequestPricing, Message, StreamChunk, TokenUsage, UserMessage } from '@deepseek-ai/dsh-llm' import { AttachmentId } from '@deepseek-ai/dsh-attachment' @@ -274,29 +274,24 @@ describe('request projection pricing', () => { } }) - it('prices nested tool-result images through the same route pricing', async () => { + it('prices tool-result images through the same route pricing', async () => { const { meter, session } = await harness(() => fixedPricing) - const nested = createUserMessage({ - content: [{ - type: 'tool-result', - toolCallId: 'call-1' as never, - content: [ - { type: 'text', text: 'screenshot below' }, - { type: 'image', attachment: imageRef('nested') }, - ], - }], - source: { kind: 'user' }, + const result = createToolResultMessage({ + callId: ToolCallId('call-1'), + content: [ + { type: 'text', text: 'screenshot below' }, + { type: 'image', attachment: imageRef('nested') }, + ], + isError: false, }) - session.append('user/message', nested, { surfaceOp: 'append' }) + session.append('tool/result', { turn: 1, step: 1, message: result }, { surfaceOp: 'append' }) session.append('request/header', { header: header('vision'), reason: 'initial' }) const measurement = meter.measure(session) - const imageFree = estimateMessage({ - ...nested, - content: [{ - ...nested.content[0] as Extract, - content: [{ type: 'text', text: 'screenshot below' }], - }], - }) + const imageFree = estimateMessage(createToolResultMessage({ + callId: ToolCallId('call-1'), + content: [{ type: 'text', text: 'screenshot below' }], + isError: false, + })) expect(measurement.nodes[0]!.tokens) .toBe(imageFree + VISUAL_TOKENS + estimateContent([{ type: 'text', text: HANDLE_TEXT }])) }) diff --git a/packages/llm/token-meter/tests/token-meter.spec.ts b/packages/llm/token-meter/tests/token-meter.spec.ts index e795ea5507..b5a719fd3b 100644 --- a/packages/llm/token-meter/tests/token-meter.spec.ts +++ b/packages/llm/token-meter/tests/token-meter.spec.ts @@ -1,39 +1,40 @@ import { describe, expect, expectTypeOf, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import { AssistantStreamAccumulator, createUserMessage, createSystemMessage, ToolCallId, createMessage } from '@deepseek-ai/dsh-llm' +import { AssistantStreamAccumulator, createAssistantMessage, createUserMessage, createSystemMessage, ToolCallId, createMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, Message, TokenUsage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, SessionSeq, canonicalHeader } from '@deepseek-ai/dsh-session' import type { EpochHeader, SessionEvent, SessionSeq as SessionSeqType } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import TokenMeter from '@deepseek-ai/dsh-token-meter' import type { TokenMeasurement, TokenMeterConfig } from '@deepseek-ai/dsh-token-meter' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + function header(model: string, extras: Omit = {}): EpochHeader { return canonicalHeader({ config: { provider: 'mock', model }, ...extras }) } -function textMessage(text: string, role: Message['role'] = 'user'): Message { - return createMessage({ - role, - content: [{ type: 'text', text }], - source: role === 'assistant' - ? { kind: 'model', provider: 'mock', model: 'mock' } - : { kind: 'user' }, - }) +function textMessage(text: string, role: 'user' | 'assistant' = 'user'): Message { + return role === 'assistant' + ? createAssistantMessage({ content: [{ type: 'text', text }], source: { provider: 'mock', model: 'mock' } }) + : createUserMessage({ content: [{ type: 'text', text }], source: { kind: 'user' } }) } function appendHeader(session: Session, value: EpochHeader): void { session.append('request/header', { header: value, reason: 'initial' }) } -const SYSTEM_PLUGIN = '@deepseek-ai/dsh-system-prompt' - /** Append the rendered system prompt as surface node 0, the way the loop does. */ function appendSystem(session: Session, text: string): SessionSeqType { return session.append('system/message', { turn: 1, step: 1, - message: createSystemMessage(text, SYSTEM_PLUGIN), + message: createSystemMessage(text), }, { surfaceOp: 'append' }).seq } @@ -42,7 +43,7 @@ function replaceSystem(session: Session, node: SessionSeqType, text: string): Se return session.append('system/message', { turn: 1, step: 1, - message: createSystemMessage(text, SYSTEM_PLUGIN), + message: createSystemMessage(text), }, { surfaceOp: { op: 'replace', startSeq: node, endSeq: node }, sourceEventSeqs: [node] }).seq } @@ -148,17 +149,12 @@ describe('TokenMeter pricing', () => { { type: 'text', text: 'abcd' }, { type: 'reasoning', text: 'ab' }, { type: 'tool-call', id: ToolCallId('c'), name: 'read', arguments: '{"x":1}' }, - { - type: 'tool-result', - toolCallId: ToolCallId('c'), - content: [{ type: 'text', text: 'xy' }], - isError: false, - }, + { type: 'text', text: 'xy' }, { type: 'future-block', payload: 'abcd' } as unknown as ContentBlock, ] const estimated = service.estimateMessage(createMessage({ role: 'assistant', content: blocks, - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'model', provider: 'mock', model: 'mock' }, })) expect(estimated).toBeGreaterThan(30) expect(service.estimateMessage(textMessage('abcd'))).toBe(9) @@ -330,7 +326,7 @@ describe('replay anchors and surface folds', () => { const assistant = anchored.nodes[1]!.seq session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'short' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: assistant, endSeq: assistant }, sourceEventSeqs: [assistant], @@ -432,7 +428,7 @@ describe('replay anchors and surface folds', () => { const first = seeded.surface.nodes[0]! seeded.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'replacement' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: first, endSeq: first }, sourceEventSeqs: [first] }) const after = service.measure(seeded) expect(after.nodes).toHaveLength(2) diff --git a/packages/llm/token-meter/tests/token-usage-projection.spec.ts b/packages/llm/token-meter/tests/token-usage-projection.spec.ts index 34c00ab3dc..b34e6e31ff 100644 --- a/packages/llm/token-meter/tests/token-usage-projection.spec.ts +++ b/packages/llm/token-meter/tests/token-usage-projection.spec.ts @@ -8,8 +8,15 @@ import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import TokenMeter from '@deepseek-ai/dsh-token-meter' import type { ContextPressureProjection, TokenUsageProjection } from '@deepseek-ai/dsh-token-meter/client' import { RetryId } from '@deepseek-ai/dsh-llm-retry' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { CompactionId } from '@deepseek-ai/dsh-compaction' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const ZERO: TokenUsageProjection = { uncachedInputTokens: 0, outputTokens: 0, @@ -273,7 +280,7 @@ describe('tokenUsage session projection', () => { appendSummaryMeter(ctx, session, before.seq, before.seq) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: before.seq, endSeq: before.seq }, sourceEventSeqs: [before.seq], @@ -476,7 +483,7 @@ describe('contextPressure session projection', () => { appendSummaryMeter(ctx, session, question, grown) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: question, endSeq: grown }, sourceEventSeqs: [question, answer, grown], @@ -494,7 +501,7 @@ describe('contextPressure session projection', () => { appendSummaryMeter(ctx, session, first, last) const target = endpoint === 'start' ? last : first session.append('user/message', createUserMessage({ - content: [{ type: 'text', text: 'summary' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'summary' }], source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: target, endSeq: target }, sourceEventSeqs: [target] }) expect(() => pressure(ctx, session)).toThrow('has no adjacent shadow price') } finally { @@ -512,7 +519,7 @@ describe('contextPressure session projection', () => { session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'summary without a preceding claim' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: question, endSeq: question }, sourceEventSeqs: [question], @@ -533,7 +540,7 @@ describe('contextPressure session projection', () => { appendSummaryMeter(ctx, session, question, question) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: '.' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: question, endSeq: question }, sourceEventSeqs: [question], diff --git a/packages/plan/plan-mode/src/index.ts b/packages/plan/plan-mode/src/index.ts index f2c53c27a4..fd950296df 100644 --- a/packages/plan/plan-mode/src/index.ts +++ b/packages/plan/plan-mode/src/index.ts @@ -28,6 +28,7 @@ import { z as zod } from 'zod' import type { ZodType } from 'zod' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import type { Session, UserMessage } from '@deepseek-ai/dsh-session' import { defineTool } from '@deepseek-ai/dsh-tools' import { UserQuestionError } from '@deepseek-ai/dsh-user-questions' @@ -35,6 +36,11 @@ import type { CommandDefinitionId, CommandId } from '@deepseek-ai/dsh-commands' import type {} from '@deepseek-ai/dsh-session-projection' import type { ProjectionDefinition } from '@deepseek-ai/dsh-session-projection' import type { PlanProjection, PlanUnitState } from './types.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'plan-mode': { kind: 'plan-mode' } & ContextFormed + } +} export type * from './types.ts' declare module '@deepseek-ai/dsh-session/types' { @@ -458,7 +464,7 @@ export class PlanModeController extends Service { return createUserMessage({ content: [{ type: 'text', text }], // The narration is already one sentence, so it is its own summary. - source: { kind: 'plugin', plugin: 'plan-mode', form: 'notice', summary: text }, + source: { kind: 'plan-mode', form: 'notice', summary: text }, }) } } diff --git a/packages/plan/plan-mode/tests/integration.spec.ts b/packages/plan/plan-mode/tests/integration.spec.ts index ac82e45822..b1742a1ba2 100644 --- a/packages/plan/plan-mode/tests/integration.spec.ts +++ b/packages/plan/plan-mode/tests/integration.spec.ts @@ -122,9 +122,9 @@ describe('plan mode through the agent loop', () => { // guidance alone (enforcement lives on the independent sandbox/approval // axes). The mode itself stays plan throughout. const result = findEvent(log, 'tool/result') - expect(result.data.message.content[0].isError).toBe(false) + expect(result.data.message.isError).toBe(false) expect(planActive(ctx, agent)).toBe(true) - expect(log.some(event => event.type === 'user/message' && event.data.source.kind === 'plugin')).toBe(false) + expect(log.some(event => event.type === 'user/message' && event.data.source.kind !== 'user')).toBe(false) }) it('a user flip between turns lands at the boundary: one notice and a replaced system node with stable tool schemas', async () => { @@ -149,7 +149,7 @@ describe('plan mode through the agent loop', () => { const log = agent.session.snapshotEvents() expect(planActive(ctx, agent)).toBe(true) - const notices = log.filter(event => event.type === 'user/message' && event.data.source.kind === 'plugin') + const notices = log.filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(notices).toHaveLength(1) expect(notices[0]?.type === 'user/message' && notices[0].data.content).toEqual([ { type: 'text', text: 'The user switched this session to plan mode.' }, @@ -218,7 +218,7 @@ describe('plan mode through the agent loop', () => { expect(systemNodes[1]?.sourceEventSeqs).toEqual([systemNodes[0]?.seq]) expect(nextStart?.seq).toBeLessThan(systemNodes[1]?.seq ?? 0) expect(systemText(agent)).toContain(PLAN_CONFIG.section) - const notice = log.find(event => event.type === 'user/message' && event.data.source.kind === 'plugin') + const notice = log.find(event => event.type === 'user/message' && event.data.source.kind !== 'user') expect(notice?.type === 'user/message' && notice.data.content).toEqual([ { type: 'text', text: 'The user switched this session to plan mode.' }, ]) diff --git a/packages/plan/plan-mode/tests/plan-mode.spec.ts b/packages/plan/plan-mode/tests/plan-mode.spec.ts index bdabf94997..112144c893 100644 --- a/packages/plan/plan-mode/tests/plan-mode.spec.ts +++ b/packages/plan/plan-mode/tests/plan-mode.spec.ts @@ -143,7 +143,7 @@ function header(session: Session): void { function noticeTexts(session: Session): string[] { return session.snapshotEvents() - .filter(event => event.type === 'user/message' && event.data.source.kind === 'plugin') + .filter(event => event.type === 'user/message' && event.data.source.kind !== 'user') .map(event => (event.data as { content: { type: string; text?: string }[] }).content.map(block => block.text ?? '').join('')) } diff --git a/packages/schedule/schedule/src/runtime.ts b/packages/schedule/schedule/src/runtime.ts index 1574574c3d..2da746ce77 100644 --- a/packages/schedule/schedule/src/runtime.ts +++ b/packages/schedule/schedule/src/runtime.ts @@ -6,6 +6,13 @@ import type { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'schedule': { kind: 'schedule' } & ContextFormed + } +} + import type { EveryScheduleRecord, OneShotScheduleRecord } from './types.ts' import { foldScheduleEvents, @@ -268,7 +275,7 @@ export class ScheduleRuntime { : renderEveryReminderBatchFraming(decision.reminders) const message = createUserMessage({ content: [{ type: 'text', text }], - source: { kind: 'plugin', plugin: 'schedule' }, + source: { kind: 'schedule' }, }) this.agent.followup(message) } catch (error: unknown) { diff --git a/packages/schedule/schedule/tests/runtime.spec.ts b/packages/schedule/schedule/tests/runtime.spec.ts index 5c415c7c6b..d86859ac50 100644 --- a/packages/schedule/schedule/tests/runtime.spec.ts +++ b/packages/schedule/schedule/tests/runtime.spec.ts @@ -259,7 +259,7 @@ describe('Schedule timer and admission runtime', () => { 'reminder_prompt_json: "line\\noccurrence_at: forged"', ].join('\n'), }]) - expect(test.followed[0]?.source).toEqual({ kind: 'plugin', plugin: 'schedule' }) + expect(test.followed[0]?.source).toEqual({ kind: 'schedule' }) await runtime.dispose() }) @@ -297,7 +297,7 @@ describe('Schedule timer and admission runtime', () => { 'reminders_json: [{"schedule_id":"schedule-fast","occurrence_at":"2026-08-05T12:00:00.000Z","reminder_prompt":"fast"},{"schedule_id":"schedule-slow","occurrence_at":"2026-08-05T11:59:00.000Z","reminder_prompt":"slow"}]', ].join('\n'), }]) - expect(test.followed[0]?.source).toEqual({ kind: 'plugin', plugin: 'schedule' }) + expect(test.followed[0]?.source).toEqual({ kind: 'schedule' }) const dispatches = test.agent.session.snapshotEvents().filter(event => event.type === 'schedule/change' && event.data.operation === 'dispatch') expect(dispatches.map(event => event.data)).toEqual([ diff --git a/packages/sdk/server/src/server.ts b/packages/sdk/server/src/server.ts index 031508993b..bdb58687da 100644 --- a/packages/sdk/server/src/server.ts +++ b/packages/sdk/server/src/server.ts @@ -121,7 +121,9 @@ export class HarnessSdkJsonRpcServer { childSessionId: String(info.id), status: successStatus(info.stopReason, serverOptions), stopReason: info.stopReason, - ...(info.lastAssistantMessage === undefined ? {} : { lastAssistantMessage: info.lastAssistantMessage }), + ...(info.lastAssistantMessage === undefined + ? {} + : { lastAssistantMessage: [...info.lastAssistantMessage] }), } transport.notify('subagent.finished', payload) })) diff --git a/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts b/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts index a4657aeea3..dd1fb10489 100644 --- a/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts +++ b/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts @@ -1,4 +1,5 @@ import { createAssistantMessage, createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' import { Context, type Fiber } from '@deepseek-ai/cordis' import { DatabaseSync } from 'node:sqlite' @@ -34,6 +35,12 @@ import { type SessionSearchRequest, } from '@deepseek-ai/dsh-session-query' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const temporaryDirectories: string[] = [] afterEach(async () => { @@ -407,7 +414,7 @@ describe('SQLite session search', () => { }, }, { type: 'user/message', seq: SessionSeq(2), time: 12, data: createUserMessage({ - content: [{ type: 'text', text: 'needle summary' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'needle summary' }], source: { kind: 'test' }, }), surfaceOp: { op: 'replace', startSeq: SessionSeq(0), endSeq: SessionSeq(0) }, sourceEventSeqs: [SessionSeq(0)] }, { type: 'turn/end', seq: SessionSeq(3), time: 13, data: { turn: 1, reason: { kind: 'error', error: { message: 'needle failure', code: 'UNKNOWN' } } } }, ] diff --git a/packages/session-query/session-query/src/extraction.ts b/packages/session-query/session-query/src/extraction.ts index f31bfb4c5f..198b118197 100644 --- a/packages/session-query/session-query/src/extraction.ts +++ b/packages/session-query/session-query/src/extraction.ts @@ -75,8 +75,6 @@ function blockText(block: SessionContentBlock): string[] { return [] case 'tool-call': return [block.name, block.arguments] - case 'tool-result': - return block.content.flatMap(blockText) // ContentBlockMap is merge-extensible. Unknown blocks do not become // searchable merely because their payload happens to contain strings. default: diff --git a/packages/session-query/session-query/tests/search-helpers.spec.ts b/packages/session-query/session-query/tests/search-helpers.spec.ts index b8021a9e64..ccbc4430a7 100644 --- a/packages/session-query/session-query/tests/search-helpers.spec.ts +++ b/packages/session-query/session-query/tests/search-helpers.spec.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createUserMessage, ToolCallId , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SESSION_FORMAT_VERSION, SessionId, @@ -21,6 +22,12 @@ import { } from '@deepseek-ai/dsh-session-query' import { TestSessionQueryEngine } from './test-service.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const id = SessionId('session') function header(value: string, extra: Partial = {}): SessionHeader { @@ -38,12 +45,8 @@ describe('session-query semantic extraction', () => { { type: 'text', text: ' visible ' }, { type: 'reasoning', text: 'thought' }, { type: 'tool-call', id: callId, name: 'read', arguments: '{"path":"a"}' }, - { - type: 'tool-result', - toolCallId: callId, - content: [{ type: 'text', text: 'nested' }], - isError: false, - }, + { type: 'text', text: 'nested' }, + { type: 'plugin:text', text: 'opaque hidden', content: [{ type: 'text', text: 'hidden child' }] } as never, { type: 'future-content', payload: 'hidden' } as never, ] const events: SessionEvent[] = [ @@ -63,7 +66,7 @@ describe('session-query semantic extraction', () => { }), }, surfaceOp: 'append' }, { type: 'user/message', seq: SessionSeq(2), time: 3, data: createUserMessage({ - content: messageContent, source: { kind: 'plugin', plugin: 'test' }, + content: messageContent, source: { kind: 'test' }, }), surfaceOp: 'append' }, { type: 'tool/call', seq: SessionSeq(3), time: 5, data: { turn: 1, step: 1, callId, name: 'bash', arguments: '{"cmd":"pwd"}' } }, { @@ -174,7 +177,7 @@ describe('session-query document and filter helpers', () => { { type: 'user/message', seq: SessionSeq(2), time: 12, data: createUserMessage({ content: [{ type: 'text', text: 'replacement' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), surfaceOp: { op: 'replace', startSeq: SessionSeq(0), endSeq: SessionSeq(0) }, sourceEventSeqs: [SessionSeq(0)] }, @@ -250,7 +253,7 @@ describe('session-query document and filter helpers', () => { time: 1, data: createUserMessage({ content: [{ type: 'text', text: 'bad' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), surfaceOp: { op: 'replace', startSeq: SessionSeq(9), endSeq: SessionSeq(9) }, }] diff --git a/packages/session-query/session-query/tests/session-query.spec.ts b/packages/session-query/session-query/tests/session-query.spec.ts index ea89275ef3..d6650e81b3 100644 --- a/packages/session-query/session-query/tests/session-query.spec.ts +++ b/packages/session-query/session-query/tests/session-query.spec.ts @@ -1,4 +1,5 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed, MessageSource } from '@deepseek-ai/dsh-llm' import { describe, expect, it, vi } from 'vitest' import { Context, type Fiber } from '@deepseek-ai/cordis' import SessionStore, { SessionLogOffset, SessionSeq, SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' @@ -25,6 +26,19 @@ import SessionQueryEngine, { import { SessionTitleProviderId, SessionTitleService } from '@deepseek-ai/dsh-session-title' import { TestSessionQueryEngine } from './test-service.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + +type CheckpointSource = Extract + +/** Build a typed checkpoint source for a query fixture without owning compaction. */ +function checkpointSource(compactionId: string): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: compactionId as CheckpointSource['compactionId'] } +} + const TITLE_SERVICE_CONFIG = { fallbackMaxWords: 8, fallbackMaxBytes: 64, maxTitleBytes: 256 } function header(id: string, createdAt = 1, extra: Partial = {}): SessionHeader { @@ -959,7 +973,7 @@ describe('session-query exact reads', () => { 'user/message', createUserMessage({ content: [{ type: 'text', text: 'replacement' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: first.seq, endSeq: first.seq }, sourceEventSeqs: [first.seq] }, ) @@ -986,7 +1000,7 @@ describe('session-query exact reads', () => { session.append( 'user/message', createUserMessage({ - content: [{ type: 'text', text: 'checkpoint' }], source: { kind: 'plugin', plugin: 'compact' }, + content: [{ type: 'text', text: 'checkpoint' }], source: checkpointSource('query-compaction-1'), }), { surfaceOp: { op: 'replace', startSeq: first.seq, endSeq: first.seq }, sourceEventSeqs: [first.seq] }, ) @@ -1000,7 +1014,7 @@ describe('session-query exact reads', () => { session.append( 'user/message', createUserMessage({ - content: [{ type: 'text', text: 'latest checkpoint' }], source: { kind: 'plugin', plugin: 'compact' }, + content: [{ type: 'text', text: 'latest checkpoint' }], source: checkpointSource('query-compaction-2'), }), { surfaceOp: { op: 'replace', startSeq: SessionSeq(2), endSeq: retained.seq }, sourceEventSeqs: [SessionSeq(2), retained.seq] }, ) @@ -1030,7 +1044,7 @@ describe('session-query exact reads', () => { ]) if (snapshot.events[0]?.type !== 'user/message') throw new Error('expected current user message') expect(() => { - (snapshot.events[0]!.data as { content: unknown[] }).content = [] + (snapshot.events[0]!.data as unknown as { content: unknown[] }).content = [] }).toThrow() Object.assign(snapshot.session, { cwd: '/mutated' }) diff --git a/packages/session-query/session-query/tests/tracing.spec.ts b/packages/session-query/session-query/tests/tracing.spec.ts index 177edad1d7..8cdd8c4b84 100644 --- a/packages/session-query/session-query/tests/tracing.spec.ts +++ b/packages/session-query/session-query/tests/tracing.spec.ts @@ -1,4 +1,5 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionLogOffset, SessionSeq, SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' @@ -18,6 +19,12 @@ import type { import { type SessionQueryErrorCode } from '@deepseek-ai/dsh-session-query' import { TestSessionQueryEngine } from './test-service.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + type MutableSessionHeader = { -readonly [K in keyof SessionHeader]: SessionHeader[K] } /** Test-only mutable view used to verify detached returned metadata. */ @@ -158,7 +165,7 @@ function appendTraceEvents(session: Session): void { 'user/message', createUserMessage({ content: [{ type: 'text', text: 'summary one' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: SessionSeq(3), endSeq: SessionSeq(3) }, @@ -168,7 +175,7 @@ function appendTraceEvents(session: Session): void { session.append( 'user/message', createUserMessage({ - content: [{ type: 'text', text: 'context' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'context' }], source: { kind: 'test' }, }), { surfaceOp: 'append' }, ) @@ -178,7 +185,7 @@ function appendTraceEvents(session: Session): void { 'user/message', createUserMessage({ content: [{ type: 'text', text: 'summary two' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: SessionSeq(4), endSeq: SessionSeq(4) }, @@ -378,7 +385,7 @@ describe('session event tracing', () => { live.append( 'user/message', createUserMessage({ - content: [{ type: 'text', text: 'live' }], source: { kind: 'plugin', plugin: 'test' }, + content: [{ type: 'text', text: 'live' }], source: { kind: 'test' }, }), { surfaceOp: 'append' }, ) diff --git a/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts b/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts index c127c2a127..3d11ad3f85 100644 --- a/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts +++ b/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts @@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { Context, type Fiber } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, ToolCallId, HarnessError , createMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { MAX_TIMER_DELAY_MS, TimeoutReason } from '@deepseek-ai/dsh-timeout' import * as TimeoutPolicy from '@deepseek-ai/dsh-tool-call-timeout-policy' import SessionStore, { @@ -32,6 +33,12 @@ import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime, { type ToolExecutionResult } from '@deepseek-ai/dsh-tools' import * as ToolSessionQuery from '@deepseek-ai/dsh-tool-session-query' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + const activeContexts: Context[] = [] afterEach(async () => { @@ -1221,7 +1228,7 @@ describe('workspace authority and lineage redaction', () => { 'context/message', { content: [{ type: 'text', text: 'same-id moved secret' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }, ) const window = await mounted.ctx.sessionQuery.readEvent({ @@ -1995,7 +2002,7 @@ describe('trace and exact read rendering', () => { 'user/message', createUserMessage({ content: [{ type: 'text', text: 'replacement' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: { op: 'replace', startSeq: SessionSeq(0), endSeq: SessionSeq(0) }, @@ -2042,7 +2049,7 @@ describe('trace and exact read rendering', () => { ) => SessionEvent appendLegacy( 'context/message', - { content: [{ type: 'text', text: 'after semantic text' }], source: { kind: 'plugin', plugin: 'test' } }, + { content: [{ type: 'text', text: 'after semantic text' }], source: { kind: 'test' } }, ) const result = await mounted.call('session_event_read', { session_id: session.id, diff --git a/packages/session/README.i18n.yaml b/packages/session/README.i18n.yaml index d7a451cf3c..a8c4662bfd 100644 --- a/packages/session/README.i18n.yaml +++ b/packages/session/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/session/README.md -README.md: 86d3c2ce9467fda0cdc6cc2ee255be75960e7a45 -README.zh.md: f7b0ea006e2cba24e727bd6f2860583778a9d6ab +README.md: 989a98f4b89ebf9ef66a05499e003bd13b6532ee +README.zh.md: 4f9a553188b6f49e0bafc6222581e147d8132a2d diff --git a/packages/session/README.md b/packages/session/README.md index 86d3c2ce94..989a98f4b8 100644 --- a/packages/session/README.md +++ b/packages/session/README.md @@ -31,6 +31,8 @@ The group splits into four families: durable storage (persistence seam, backends | [`session-format/`](session-format/README.md) | Pure adjacent-format chain and artifact validation library | library — no ctx key | | [`session-format-v0-to-v1/`](session-format-v0-to-v1/README.md) | Frozen released-v0 decoder and identity migration into released v1 | library — no ctx key | | [`session-format-v1-to-v2/`](session-format-v1-to-v2/README.md) | Frozen released-v1 decoder and cardinality-changing Assistant-stream migration into released v2 | library — no ctx key | +| [`session-format-v2-to-v3/`](session-format-v2-to-v3/README.md) | Frozen V2 decoder and system-prompt, envelope, and PTC migration into V3 | library — no ctx key | +| [`session-format-v3-to-v4/`](session-format-v3-to-v4/README.md) | V3 identity migration and V4 codec with generation-aware delivery validation | library — no ctx key | | [`session-format-catalog/`](session-format-catalog/README.md) | Generated static catalog of shipped adjacent migrations | library — no ctx key | | [`session-persistence/`](session-persistence/README.md) | Defines the durable session-storage service and the shared write coordination every backend composes | `ctx.sessionPersistence` | | [`session-persistence-jsonl/`](session-persistence-jsonl/README.md) | Shipped backend: immutable canonical generation filenames per Session with exclusive successor publication, optionally Zstandard-compressed | registers on `ctx.sessionPersistence` | diff --git a/packages/session/README.zh.md b/packages/session/README.zh.md index f7b0ea006e..4f9a553188 100644 --- a/packages/session/README.zh.md +++ b/packages/session/README.zh.md @@ -31,6 +31,8 @@ session 组让对话持久保存,恢复已发布的日志格式,并使已提 | [`session-format/`](session-format/README.zh.md) | 纯相邻格式链与产物校验库 | 库,不使用 ctx key | | [`session-format-v0-to-v1/`](session-format-v0-to-v1/README.zh.md) | 冻结的 released-v0 解码器,以及到 released v1 的恒等迁移 | 库,不使用 ctx key | | [`session-format-v1-to-v2/`](session-format-v1-to-v2/README.zh.md) | 冻结的 released-v1 解码器,以及迁移到 released v2 时会改变基数的 Assistant 流迁移 | 库,不使用 ctx key | +| [`session-format-v2-to-v3/`](session-format-v2-to-v3/README.zh.md) | 冻结的 V2 解码器,以及迁入 V3 的系统提示词、信封与 PTC 转换 | 库——无 ctx 键 | +| [`session-format-v3-to-v4/`](session-format-v3-to-v4/README.zh.md) | V3 恒等迁移与 V4 编解码器,按 generation 校验 delivery | 库——无 ctx 键 | | [`session-format-catalog/`](session-format-catalog/README.zh.md) | 自动生成的已交付相邻迁移静态目录 | 库,不使用 ctx key | | [`session-persistence/`](session-persistence/README.zh.md) | 定义持久会话存储服务,以及每个后端组合的共享写入协调机制 | `ctx.sessionPersistence` | | [`session-persistence-jsonl/`](session-persistence-jsonl/README.zh.md) | 随产品交付的后端:逐 Session 使用不可变规范 generation 文件名并排他发布后继;可选 Zstandard 压缩 | 注册到 `ctx.sessionPersistence` | diff --git a/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts b/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts index f978d8acf1..eee1f54536 100644 --- a/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts +++ b/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts @@ -112,9 +112,9 @@ describe.skipIf(process.platform === 'win32')('semantic checkpoint hard-crash re expect(result?.type === 'tool/result' && result.data.error).toEqual({ name: 'ToolOutcomeUnknownError', code: TOOL_OUTCOME_UNKNOWN, }) - if (result?.type !== 'tool/result' || result.data.message.content[0].content[0]?.type !== 'text') { + if (result?.type !== 'tool/result' || result.data.message.content[0]?.type !== 'text') { throw new Error('expected a text tool result') } - expect(result.data.message.content[0].content[0].text).toContain('Do not retry blindly.') + expect(result.data.message.content[0].text).toContain('Do not retry blindly.') }) }) diff --git a/packages/session/session-format-catalog/README.i18n.yaml b/packages/session/session-format-catalog/README.i18n.yaml index 523dc45f64..31246e1ed0 100644 --- a/packages/session/session-format-catalog/README.i18n.yaml +++ b/packages/session/session-format-catalog/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/session/session-format-catalog/README.md -README.md: 8232a28b2c2c31c0176adb62e07ed16a804791e8 -README.zh.md: 2c4c86da50640f672842d98e6cc254dca08a3470 +README.md: bb86bcaffee2c2e17afffd4ce7fbd917bf1c30ee +README.zh.md: 156361ae330967169ae82e204ddeff26c50b05bd diff --git a/packages/session/session-format-catalog/README.md b/packages/session/session-format-catalog/README.md index 8232a28b2c..bb86bcaffe 100644 --- a/packages/session/session-format-catalog/README.md +++ b/packages/session/session-format-catalog/README.md @@ -33,7 +33,8 @@ Import this library from persistence and test-support readers that need the comp ```text const descriptor = sessionFormatCatalog.readHeader(physicalHeader) -const restore = sessionFormatCatalog.createRestore(physicalHeader, { recovery: 'recoverable', validation: 'transformed' }) +const catalog = createSessionFormatCatalogWithChildren(childFacts) +const restore = catalog.createRestore(physicalHeader, { recovery: 'recoverable', validation: 'transformed' }) for (const row of physicalRows) restore.decodeRow(row) const current = restore.finish() const headerRecord = sessionFormatCatalog.encodeCurrentHeader(current.header, current.inheritedEventCount) @@ -46,6 +47,8 @@ Production historical reads select `{ recovery: 'recoverable', validation: 'tran The catalog contains all supported historical readers directly. A profile cannot add, remove, or reorder an edge by mounting a feature plugin. Its peer dependency on `dsh-session` supplies the installed current event vocabulary and current restoration rules, while historical edge validators remain frozen. The browser-safe `./message-projections` export assembles current plugin-owned interpreters for detached constructors and surface folds; it does not mount recovery listeners. +`createSessionFormatCatalogWithChildren(childFacts)` binds explicit child evidence to V3→V4 during assembly; see the [catalog-completion specification](../session-format-v3-to-v4/README.md). `historicalSessionFormatCatalog` restores V0–V3 using the fixed released-V3 event vocabulary to collect child prerequisites without recursively completing their catalogs. An ignorable V3 extension remains opaque even when the installed writer knows its name. Isolated transcript replay explicitly supplies an empty array; persistence must collect the complete available direct-child set. Keep the supplied evidence unchanged for the catalog’s lifetime. Each restore owns independent stage state. The static `sessionFormatCatalog` supports header and native current-format reads; historical body reads require the child-bound catalog. + ----- @@ -67,6 +70,7 @@ The catalog contains all supported historical readers directly. A profile cannot - [Released v0 to v1 edge](../session-format-v0-to-v1/README.md) — codec and validator ownership. - [Released v1 to v2 edge](../session-format-v1-to-v2/README.md) — Assistant stream embedding and cardinality-changing reference remapping. - [Released V2 to V3 specification](../session-format-v2-to-v3/README.md#v2-to-v3-specification) — transformations, preservation, and refusal. +- [V3 to V4 specification](../session-format-v3-to-v4/README.md#v3-to-v4-specification) — identity conversion and delivery-generation validation. - [JSONL persistence](../session-persistence-jsonl/README.md) — immutable generation naming and exclusive publication. ----- diff --git a/packages/session/session-format-catalog/README.zh.md b/packages/session/session-format-catalog/README.zh.md index 2c4c86da50..156361ae33 100644 --- a/packages/session/session-format-catalog/README.zh.md +++ b/packages/session/session-format-catalog/README.zh.md @@ -33,7 +33,8 @@ kind: "package-library" ```text const descriptor = sessionFormatCatalog.readHeader(physicalHeader) -const restore = sessionFormatCatalog.createRestore(physicalHeader, { recovery: 'recoverable', validation: 'transformed' }) +const catalog = createSessionFormatCatalogWithChildren(childFacts) +const restore = catalog.createRestore(physicalHeader, { recovery: 'recoverable', validation: 'transformed' }) for (const row of physicalRows) restore.decodeRow(row) const current = restore.finish() const headerRecord = sessionFormatCatalog.encodeCurrentHeader(current.header, current.inheritedEventCount) @@ -46,6 +47,8 @@ Production 历史读取使用 `{ recovery: 'recoverable', validation: 'transform 该目录直接包含所有受支持的历史读取器。Profile 无法通过挂载功能插件来添加、移除或重新排列迁移边。它通过对 `dsh-session` 的对等依赖(peer dependency)获得已安装的当前事件词表与当前还原规则,而历史迁移边校验器保持冻结。浏览器安全的 `./message-projections` 导出为独立构造函数和 surface 折叠装配当前插件拥有的处理器,不挂载恢复监听器。 +`createSessionFormatCatalogWithChildren(childFacts)` 在组装时将显式的子 Session 证据绑定到 V3→V4,见[目录补齐规范](../session-format-v3-to-v4/README.zh.md)。`historicalSessionFormatCatalog` 使用固定的已发布 V3 事件词汇恢复 V0–V3,收集子日志前置事实而不递归补齐其目录。即使已安装写入方认识事件名,可忽略 V3 扩展仍保持不透明。独立转录回放显式提供空数组;持久化必须收集完整的可用直属子 Session 集合。在 catalog 的生命周期内保持传入证据不变。每次恢复各自拥有独立的 stage 状态。静态 `sessionFormatCatalog` 支持 header 和原生当前格式读取;历史正文读取必须使用已绑定子 Session 的 catalog。 + ----- @@ -67,6 +70,7 @@ Production 历史读取使用 `{ recovery: 'recoverable', validation: 'transform - [已发布 v0 到 v1 迁移边](../session-format-v0-to-v1/README.zh.md)——编解码器与校验器所有权。 - [已发布 v1 到 v2 迁移边](../session-format-v1-to-v2/README.zh.md)——Assistant 流嵌入与基数变化引用重映射。 - [已发布 V2 到 V3 规范](../session-format-v2-to-v3/README.zh.md#v2-to-v3-specification)——转换、保留与拒绝。 +- [V3 到 V4 规范](../session-format-v3-to-v4/README.zh.md#v3-to-v4-specification)——恒等转换与 delivery generation 校验。 - [JSONL 持久化](../session-persistence-jsonl/README.zh.md)——不可变 generation 命名与排他发布。 ----- diff --git a/packages/session/session-format-catalog/package.json b/packages/session/session-format-catalog/package.json index 67ad97eaa7..5009d93f6d 100644 --- a/packages/session/session-format-catalog/package.json +++ b/packages/session/session-format-catalog/package.json @@ -36,6 +36,7 @@ "@deepseek-ai/dsh-session-format-v0-to-v1": "workspace:^", "@deepseek-ai/dsh-session-format-v1-to-v2": "workspace:^", "@deepseek-ai/dsh-session-format-v2-to-v3": "workspace:^", + "@deepseek-ai/dsh-session-format-v3-to-v4": "workspace:^", "@deepseek-ai/dsh-compaction-image-offload": "workspace:^" }, "peerDependencies": { diff --git a/packages/session/session-format-catalog/src/children.ts b/packages/session/session-format-catalog/src/children.ts new file mode 100644 index 0000000000..580e46d2ae --- /dev/null +++ b/packages/session/session-format-catalog/src/children.ts @@ -0,0 +1,19 @@ +/** Bind parent-specific child evidence into the static first-party migration inventory. */ + +import { createSessionFormatCatalog } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatCatalog, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatV3ToV4, sessionFormatV3ToV4 } from '@deepseek-ai/dsh-session-format-v3-to-v4' +import { sessionFormatCatalogOptions } from './generated.ts' + +/** + * Assemble a catalog whose V3→V4 edge knows one parent's historical children. + * @param children - complete child evidence retained unchanged for the catalog's lifetime; an empty array declares no children. + * @returns a catalog with independent restore state per artifact and unchanged current-format readers. + */ +export function createSessionFormatCatalogWithChildren(children: readonly SessionFormatJsonValue[]): SessionFormatCatalog { + const migration = createSessionFormatV3ToV4(children) + return createSessionFormatCatalog({ + ...sessionFormatCatalogOptions, + migrations: sessionFormatCatalogOptions.migrations.map(edge => edge === sessionFormatV3ToV4 ? migration : edge), + }) +} diff --git a/packages/session/session-format-catalog/src/generated.ts b/packages/session/session-format-catalog/src/generated.ts index f726d954d9..eab9d91456 100644 --- a/packages/session/session-format-catalog/src/generated.ts +++ b/packages/session/session-format-catalog/src/generated.ts @@ -5,28 +5,44 @@ import { KNOWN_SESSION_EVENT_TYPES } from '@deepseek-ai/dsh-session' import { createSessionFormatCatalog } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatCatalogOptions } from '@deepseek-ai/dsh-session-format' import { validateInstalledCurrentSessionArtifact, validateInstalledCurrentSessionHeader } from './current.ts' import { releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, sessionFormatV0ToV1 } from '@deepseek-ai/dsh-session-format-v0-to-v1' import { releasedV2SessionFormatCodec, sessionFormatV1ToV2 } from '@deepseek-ai/dsh-session-format-v1-to-v2' -import { assertReleasedV3Header, releasedV3SessionFormatCodec, restoreReleasedV3Artifact, sessionFormatV2ToV3 } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { releasedV3SessionFormatCodec, sessionFormatV2ToV3 } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { assertReleasedV4Header, releasedV4SessionFormatCodec, restoreReleasedV4Artifact, sessionFormatV3ToV4 } from '@deepseek-ai/dsh-session-format-v3-to-v4' -/** Physical codec dispatch and complete adjacent chain, independent of mounted plugins. */ -export const sessionFormatCatalog = createSessionFormatCatalog({ - currentVersion: 3, - codecs: [releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, releasedV2SessionFormatCodec, releasedV3SessionFormatCodec], - currentEncoder: releasedV3SessionFormatCodec, - migrations: [sessionFormatV0ToV1, sessionFormatV1ToV2, sessionFormatV2ToV3], +/** Static assembly shared by current reads and parent-specific historical restoration. */ +export const sessionFormatCatalogOptions: SessionFormatCatalogOptions = { + currentVersion: 4, + codecs: [ + releasedV0SessionFormatCodec, + releasedV1SessionFormatCodec, + releasedV2SessionFormatCodec, + releasedV3SessionFormatCodec, + releasedV4SessionFormatCodec, + ], + currentEncoder: releasedV4SessionFormatCodec, + migrations: [ + sessionFormatV0ToV1, + sessionFormatV1ToV2, + sessionFormatV2ToV3, + sessionFormatV3ToV4, + ], restoreCurrent(artifact) { - const restored = restoreReleasedV3Artifact(artifact, KNOWN_SESSION_EVENT_TYPES) + const restored = restoreReleasedV4Artifact(artifact, KNOWN_SESSION_EVENT_TYPES) validateInstalledCurrentSessionArtifact(restored) return restored }, restoreTransformedCurrent(artifact) { - return restoreReleasedV3Artifact(artifact, KNOWN_SESSION_EVENT_TYPES) + return restoreReleasedV4Artifact(artifact, KNOWN_SESSION_EVENT_TYPES) }, restoreCurrentHeader(header) { - assertReleasedV3Header(header) + assertReleasedV4Header(header) validateInstalledCurrentSessionHeader(header) return header }, -}) +} + +/** Physical codec dispatch and complete adjacent chain, independent of mounted plugins. */ +export const sessionFormatCatalog = createSessionFormatCatalog(sessionFormatCatalogOptions) diff --git a/packages/session/session-format-catalog/src/historical.ts b/packages/session/session-format-catalog/src/historical.ts new file mode 100644 index 0000000000..e04434ce72 --- /dev/null +++ b/packages/session/session-format-catalog/src/historical.ts @@ -0,0 +1,21 @@ +/** Historical restoration for collecting migration prerequisites without recursively opening current Sessions. */ + +import { RELEASED_V3_EVENT_TYPES } from '@deepseek-ai/dsh-session-format-v3-to-v4' +import { createSessionFormatCatalog } from '@deepseek-ai/dsh-session-format' +import { releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, sessionFormatV0ToV1 } from '@deepseek-ai/dsh-session-format-v0-to-v1' +import { releasedV2SessionFormatCodec, sessionFormatV1ToV2 } from '@deepseek-ai/dsh-session-format-v1-to-v2' +import { assertReleasedV3Header, releasedV3SessionFormatCodec, restoreReleasedV3Artifact, sessionFormatV2ToV3 } from '@deepseek-ai/dsh-session-format-v2-to-v3' + +/** V0–V3 decoding for historical child identity; never publishes or completes parent catalogs. */ +export const historicalSessionFormatCatalog = createSessionFormatCatalog({ + currentVersion: 3, + codecs: [releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, releasedV2SessionFormatCodec, releasedV3SessionFormatCodec], + currentEncoder: releasedV3SessionFormatCodec, + migrations: [sessionFormatV0ToV1, sessionFormatV1ToV2, sessionFormatV2ToV3], + restoreCurrent: artifact => restoreReleasedV3Artifact(artifact, RELEASED_V3_EVENT_TYPES), + restoreTransformedCurrent: artifact => restoreReleasedV3Artifact(artifact, RELEASED_V3_EVENT_TYPES), + restoreCurrentHeader(header) { + assertReleasedV3Header(header) + return header + }, +}) diff --git a/packages/session/session-format-catalog/src/index.ts b/packages/session/session-format-catalog/src/index.ts index 095ce7bf84..854a9c89b6 100644 --- a/packages/session/session-format-catalog/src/index.ts +++ b/packages/session/session-format-catalog/src/index.ts @@ -1,4 +1,6 @@ /** Build-static first-party Session format migration catalog. */ export { sessionFormatCatalog } from './generated.ts' +export { createSessionFormatCatalogWithChildren } from './children.ts' +export { historicalSessionFormatCatalog } from './historical.ts' export { SessionFormatUnsupportedMigrationError } from '@deepseek-ai/dsh-session-format' diff --git a/packages/session/session-format-catalog/tests/catalog.spec.ts b/packages/session/session-format-catalog/tests/catalog.spec.ts index 335f406e89..209f4aee7b 100644 --- a/packages/session/session-format-catalog/tests/catalog.spec.ts +++ b/packages/session/session-format-catalog/tests/catalog.spec.ts @@ -1,10 +1,10 @@ import { describe, expect, it } from 'vitest' import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' -import { sessionFormatCatalog } from '../src/index.ts' +import { createSessionFormatCatalogWithChildren, historicalSessionFormatCatalog, sessionFormatCatalog } from '../src/index.ts' import { currentSessionMessageProjections } from '../src/message-projections.ts' import { MESSAGE_PROJECTION_EVENT_TYPES } from '@deepseek-ai/dsh-session/src/known-event-types.ts' import { validateInstalledCurrentSessionArtifact } from '../src/current.ts' -import { Session, SessionId } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, Session, SessionId } from '@deepseek-ai/dsh-session' import { createUserMessage } from '@deepseek-ai/dsh-llm' function deepFreeze(value: T): T { @@ -27,7 +27,7 @@ describe('first-party Session format catalog', () => { } expect(() => { validateInstalledCurrentSessionArtifact(artifact) }).toThrow(/image index 0 does not exist/) }) - it('statically owns the complete adjacent v0 to v3 chain', () => { + it('statically owns every adjacent edge through the current writer', () => { const header = { type: 'session', version: 0, @@ -37,13 +37,13 @@ describe('first-party Session format catalog', () => { delegationDepth: 0, } - expect(sessionFormatCatalog.currentVersion).toBe(3) + expect(sessionFormatCatalog.currentVersion).toBe(SESSION_FORMAT_VERSION) expect(sessionFormatCatalog.readHeader(header)).toEqual({ status: 'migration-required', storedVersion: 0, - targetVersion: 3, + targetVersion: SESSION_FORMAT_VERSION, header: { - version: 3, + version: SESSION_FORMAT_VERSION, id: 'catalog', createdAt: 1, isSeeded: true, @@ -52,21 +52,21 @@ describe('first-party Session format catalog', () => { }) const v1Header = { ...header, version: 1 } - const restore = sessionFormatCatalog.createRestore(v1Header, { + const restore = createSessionFormatCatalogWithChildren([]).createRestore(v1Header, { recovery: 'strict', validation: 'current', }) restore.decodeRow({ type: 'turn/start', seq: 0, time: 2, data: { turn: 1 } }) expect(restore.finish()).toMatchObject({ - header: { version: 3, id: 'catalog' }, + header: { version: SESSION_FORMAT_VERSION, id: 'catalog' }, }) }) it('restores the installed current vocabulary without freezing ordinary payload additions', () => { const header = { - type: 'session', version: 3, id: 'current-growth', createdAt: 1, isSeeded: false, delegationDepth: 0, + type: 'session', version: SESSION_FORMAT_VERSION, id: 'current-growth', createdAt: 1, isSeeded: false, delegationDepth: 0, } const restore = (rows: readonly unknown[]) => { - const current = sessionFormatCatalog.createRestore(header, { + const current = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current', }) for (const row of rows) current.decodeRow(row) @@ -97,12 +97,12 @@ describe('first-party Session format catalog', () => { type: 'session', version, id: 'seed-chain', createdAt: 1, parentSession: 'parent', seedLength, delegationDepth: 0, } - const restore = sessionFormatCatalog.createRestore(sourceHeader, { recovery: 'strict', validation: 'current' }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(sourceHeader, { recovery: 'strict', validation: 'current' }) if (seedLength > 0) { restore.decodeRow({ type: 'feedback/record', seq: 0, time: 1, data: { text: 'inherited' } }) } const artifact = restore.finish() - expect(artifact.header.version).toBe(3) + expect(artifact.header.version).toBe(SESSION_FORMAT_VERSION) expect(artifact.inheritedEventCount).toBe(seedLength) expect(artifact.events.at(-1)).toEqual({ type: 'session/end-seed', seq: seedLength, time: 1, data: { inherited: true }, @@ -120,10 +120,10 @@ describe('first-party Session format catalog', () => { ...(isSeeded ? [{ type: 'session/end-seed', seq: 3, time: 4, data: { inherited: true } }] : []), ] const before = JSON.stringify({ header, rows }) - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) for (const row of rows) restore.decodeRow(row) expect(restore.finish()).toEqual({ - header: { version: 3, id: 'v2-identity', createdAt: 1, isSeeded, delegationDepth: 0 }, + header: { version: SESSION_FORMAT_VERSION, id: 'v2-identity', createdAt: 1, isSeeded, delegationDepth: 0 }, inheritedEventCount: isSeeded ? 4 : 0, events: [ { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, @@ -134,7 +134,7 @@ describe('first-party Session format catalog', () => { turn: 1, step: 1, message: { id: 'v2-to-v3-system-9673c4ed630de6c21ea6bd6b573094ea8e5e216843a1b572a68657499ad9667b', - role: 'system', source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, content: [], + role: 'system', source: { kind: 'system-prompt' }, content: [], }, }, }, @@ -149,7 +149,7 @@ describe('first-party Session format catalog', () => { const header = { type: 'session', version: 2, id: 'v2-unknown', createdAt: 1, isSeeded: false, delegationDepth: 0 } const row = { type: 'external/event', seq: 0, time: 1, data: { extra: ['unchanged'] }, ignorable: true } const before = JSON.stringify({ header, row }) - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation }) expect(() => { restore.decodeRow(row) }).toThrow(/cannot safely transform unclassified event external\/event/) expect(JSON.stringify({ header, row })).toBe(before) }) @@ -184,10 +184,10 @@ describe('first-party Session format catalog', () => { { type: 'turn/end', seq: 9, time: 17, data: { turn: 1, reason: { kind: 'completed' } } }, ]) const before = JSON.stringify({ sourceHeader, rows }) - const restore = sessionFormatCatalog.createRestore(sourceHeader, { recovery: 'strict', validation: 'current' }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(sourceHeader, { recovery: 'strict', validation: 'current' }) for (const row of rows) restore.decodeRow(row) const artifact = restore.finish() - const renamedMessage = (id: string) => ({ ...message(id), source: { kind: 'plugin', plugin: 'tools-ptc' } }) + const renamedMessage = (id: string) => ({ ...message(id), source: { kind: 'ptc-mode' } }) const expected = [ rows[0], rows[1], expect.objectContaining({ type: 'system/message', seq: 2 }), @@ -200,7 +200,7 @@ describe('first-party Session format catalog', () => { { ...rows[8], seq: 9 }, { ...rows[9], seq: 10 }, ] expect(artifact).toEqual({ - header: { version: 3, id: sourceHeader.id, createdAt: 1, isSeeded: false, delegationDepth: 0 }, + header: { version: SESSION_FORMAT_VERSION, id: sourceHeader.id, createdAt: 1, isSeeded: false, delegationDepth: 0 }, inheritedEventCount: 0, events: expected, }) const currentHeader = deepFreeze(sessionFormatCatalog.encodeCurrentHeader(artifact.header, artifact.inheritedEventCount)) @@ -213,16 +213,16 @@ describe('first-party Session format catalog', () => { expect(JSON.stringify({ currentHeader, currentRows })).toBe(encodedBefore) }) - it.each(['current', 'transformed'] as const)('rejects native v3 obsolete required tags with %s validation and retains ignorable tags', (validation) => { + it.each(['current', 'transformed'] as const)('rejects obsolete required tags in V3 input with %s validation and retains ignorable tags', (validation) => { const header = deepFreeze({ type: 'session', version: 3, id: 'native-ptc', createdAt: 1, isSeeded: false, delegationDepth: 0 }) for (const type of ['tool/code-dispatch-start', 'tool/code-dispatch']) { const required = deepFreeze({ type, seq: 0, time: 1, data: null }) - const rejected = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }) + const rejected = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation }) expect(() => { rejected.decodeRow(required) }).toThrow(/unknown event type/) const ignorable = deepFreeze({ ...required, ignorable: true, data: { text: 'tools-code-mode', source: { kind: 'plugin', plugin: 'tools-code-mode' } } }) - const accepted = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }) + const accepted = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation }) accepted.decodeRow(ignorable) - expect(accepted.finish().events).toEqual([ignorable]) + expect(accepted.finish().events).toEqual([{ ...ignorable, type: `plugin:${type}` }]) } }) @@ -230,7 +230,7 @@ describe('first-party Session format catalog', () => { const header = deepFreeze({ type: 'session', version: 2, id: 'v2-collision', createdAt: 1, isSeeded: false, delegationDepth: 0 }) for (const type of ['tool/ptc-dispatch-start', 'tool/ptc-dispatch']) { for (const ignorable of [false, true]) { - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation }) const row = deepFreeze({ type, seq: 0, time: 1, data: null, ...(ignorable ? { ignorable: true } : {}) }) expect(() => { restore.decodeRow(row) }).toThrow(/format v2.*ptc-dispatch/) } @@ -245,7 +245,7 @@ describe('first-party Session format catalog', () => { { type: 'tool/code-dispatch-start', seq: 1, time: 2, data, ignorable: true }, { type: 'tool/code-dispatch', seq: 2, time: 3, data: { ...data, isError: false, content: [] }, ignorable: true }, ]) - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation }) for (const row of rows) restore.decodeRow(row) expect(restore.finish().events).toEqual([ rows[0], { ...rows[1], type: 'tool/ptc-dispatch-start' }, { ...rows[2], type: 'tool/ptc-dispatch' }, @@ -254,7 +254,7 @@ describe('first-party Session format catalog', () => { it.each(['current', 'transformed'] as const)('refuses a v3 delivery marker in v2 input (%s)', (validation) => { const header = { type: 'session', version: 2, id: 'future-delivery', createdAt: 1, isSeeded: false, delegationDepth: 0 } - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation }) restore.decodeRow({ type: 'feedback/record', seq: 0, time: 1, data: { text: 'unaccepted' } }) expect(() => { restore.decodeRow({ type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 2, @@ -263,12 +263,43 @@ describe('first-party Session format catalog', () => { }).toThrow(/format v2 delivery marker claims target format v3/) }) - it('validates complete relationships after streaming migration', () => { - const stream = sessionFormatCatalog.createRestore({ - type: 'session', version: 1, id: 'invalid-stream', createdAt: 1, delegationDepth: 0, + it('finishes a streaming migration with the target header and dense rows', () => { + const stream = createSessionFormatCatalogWithChildren([]).createRestore({ + type: 'session', version: 1, id: 'streaming', createdAt: 1, delegationDepth: 0, }, { recovery: 'strict', validation: 'current' }) - stream.decodeRow({ type: 'step/start', seq: 0, time: 2, data: { turn: 1, step: 1 } }) + stream.decodeRow({ type: 'feedback/record', seq: 0, time: 2, data: { text: 'retained' } }) - expect(() => stream.finish()).toThrow(/open turn/) + expect(stream.finish()).toMatchObject({ + header: { version: 4, id: 'streaming' }, + inheritedEventCount: 0, + events: [{ type: 'feedback/record', seq: 0 }], + }) + }) +}) + +describe('historical child prerequisite catalog', () => { + it('uses the V3 event vocabulary for ignorable events whose names become known later', () => { + const header = { type: 'session', version: 3, id: 'old-extension', createdAt: 1, isSeeded: false, delegationDepth: 0 } + const rows = [ + { type: 'feedback/record', seq: 0, time: 1, data: { text: 'saved' } }, + { type: 'developer/message', seq: 1, time: 2, ignorable: true, surfaceOp: 'append', sourceEventSeqs: [0], + data: { content: [{ type: 'tool-result', toolCallId: 'opaque', content: [] }], vendor: true } }, + ] + const historical = historicalSessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const row of rows) historical.decodeRow(row) + expect(historical.finish().events).toEqual(rows) + const current = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const row of rows) current.decodeRow(row) + expect(current.finish().events).toEqual([rows[0], { ...rows[1], type: 'plugin:developer/message' }]) + }) + + it('restores V3 and preceding versions without the incoming catalog-completion edge', () => { + const header = { type: 'session', version: 2, id: 'historical', createdAt: 1, isSeeded: false, delegationDepth: 0 } + expect(historicalSessionFormatCatalog.readHeader(header)).toMatchObject({ status: 'migration-required' }) + for (const validation of ['current', 'transformed'] as const) { + const restored = historicalSessionFormatCatalog.createRestore(header, { recovery: 'strict', validation }).finish() + expect(restored.header.version).toBe(3) + expect(historicalSessionFormatCatalog.createRestore({ ...header, version: 3 }, { recovery: 'strict', validation }).finish()).toEqual(restored) + } }) }) diff --git a/packages/session/session-format-catalog/tests/children.spec.ts b/packages/session/session-format-catalog/tests/children.spec.ts new file mode 100644 index 0000000000..4b2d465e93 --- /dev/null +++ b/packages/session/session-format-catalog/tests/children.spec.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from 'vitest' +import { createSessionFormatCatalogWithChildren, sessionFormatCatalog } from '../src/index.ts' + +const header = { type: 'session', version: 3, id: 'parent', createdAt: 1, isSeeded: false, delegationDepth: 0 } +const policy = { recovery: 'strict', validation: 'current' } as const +const child = (id: string) => ({ childId: id, childCreatedAt: 2, descriptorCount: 1, + descriptor: { version: 3, provider: 'spawn', mode: 'one-shot' } }) + +describe('parent-specific catalog assembly', () => { + it('requires explicit children for historical bodies while retaining header and native V4 reads', () => { + expect(sessionFormatCatalog.readHeader(header).status).toBe('migration-required') + expect(() => sessionFormatCatalog.createRestore(header, policy)).toThrow('explicit historical child facts') + expect(createSessionFormatCatalogWithChildren([]).createRestore(header, policy).finish().events).toEqual([]) + expect(sessionFormatCatalog.createRestore({ ...header, version: 4 }, policy).finish().events).toEqual([]) + }) + + it('isolates interleaved restores and child evidence across parent catalogs', () => { + const left = createSessionFormatCatalogWithChildren([child('left-child')]) + const first = left.createRestore(header, policy) + const second = createSessionFormatCatalogWithChildren([child('right-child')]) + .createRestore({ ...header, id: 'other-parent' }, policy) + const repeated = left.createRestore(header, policy) + const row = { type: 'feedback/record', seq: 0, time: 5, data: { text: 'retained' } } + first.decodeRow(row) + second.decodeRow(row) + repeated.decodeRow(row) + const right = second.finish() + const result = first.finish() + expect(result.events).toEqual([row, { type: 'subagent/catalog', seq: 1, time: 5, + data: { version: 0, childId: 'left-child', childCreatedAt: 2, mode: 'one-shot' } }]) + expect(right.events[1]?.data).toMatchObject({ childId: 'right-child' }) + expect(repeated.finish()).toEqual(result) + const physical = sessionFormatCatalog.encodeCurrentHeader(result.header, result.inheritedEventCount) + const reopened = sessionFormatCatalog.createRestore(physical, policy) + for (const event of result.events) reopened.decodeRow(sessionFormatCatalog.encodeCurrentEvent(event)) + expect(reopened.finish()).toEqual(result) + }) +}) diff --git a/packages/session/session-format-catalog/tests/current.spec.ts b/packages/session/session-format-catalog/tests/current.spec.ts index 283f2a1029..ea1180a3be 100644 --- a/packages/session/session-format-catalog/tests/current.spec.ts +++ b/packages/session/session-format-catalog/tests/current.spec.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'vitest' +import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session' import type { SessionFormatArtifact, SessionFormatHeader } from '@deepseek-ai/dsh-session-format' import { validateInstalledCurrentSessionArtifact, @@ -6,7 +7,7 @@ import { } from '../src/current.ts' const currentHeader: SessionFormatHeader = { - version: 3, + version: SESSION_FORMAT_VERSION, id: 'installed-current', createdAt: 1, isSeeded: false, @@ -16,14 +17,14 @@ const currentHeader: SessionFormatHeader = { describe('installed current Session restoration', () => { it('rejects version skew before entering current Session validation', () => { expect(() => { validateInstalledCurrentSessionHeader({ ...currentHeader, version: 0 }) }) - .toThrow(/installed Session format is v3, got v0/) + .toThrow(`installed Session format is v${SESSION_FORMAT_VERSION}, got v0`) const artifact: SessionFormatArtifact = { header: { ...currentHeader, version: 0 }, inheritedEventCount: 0, events: [], } expect(() => { validateInstalledCurrentSessionArtifact(artifact) }) - .toThrow(/installed Session format is v3, got v0/) + .toThrow(`installed Session format is v${SESSION_FORMAT_VERSION}, got v0`) }) it('accepts only current request-header reasons and the true starts-series marker', () => { diff --git a/packages/session/session-format-catalog/tests/developer-history.spec.ts b/packages/session/session-format-catalog/tests/developer-history.spec.ts new file mode 100644 index 0000000000..d02f010514 --- /dev/null +++ b/packages/session/session-format-catalog/tests/developer-history.spec.ts @@ -0,0 +1,121 @@ +/** Initial and incremental tool definitions survive current-format restoration and forks. */ +import { describe, expect, expectTypeOf, it } from 'vitest' +import { createDeveloperMessage } from '@deepseek-ai/dsh-llm' +import type { ToolAdditionBlock, ToolSchema } from '@deepseek-ai/dsh-llm' +import { Session, SessionId, SessionLogOffset } from '@deepseek-ai/dsh-session' +import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' +import { buildForkSeed } from '@deepseek-ai/dsh-session/fork' +import { createSessionFormatCatalog } from '@deepseek-ai/dsh-session-format' +import { restoreReleasedV4Artifact } from '@deepseek-ai/dsh-session-format-v3-to-v4' +import { sessionFormatCatalogOptions } from '../src/generated.ts' +import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { sessionFormatCatalog } from '../src/index.ts' + +function restore(session: Session): Session { + const header = { ...session.header, delegationDepth: 0 } + const reader = sessionFormatCatalog.createRestore( + sessionFormatCatalog.encodeCurrentHeader(header, session.inheritedEventCount), + { recovery: 'strict', validation: 'current' }, + ) + for (const event of session.snapshotEvents()) { + reader.decodeRow(sessionFormatCatalog.encodeCurrentEvent(event as unknown as SessionFormatEvent)) + } + const artifact = reader.finish() + return Session.fromRestore(SessionId(artifact.header.id), artifact.events as SessionEvent[], + artifact.header as unknown as SessionHeader, SessionLogOffset(artifact.inheritedEventCount), 'detached') +} + +function toolStates(session: Session): (ToolSchema | undefined)[] { + const initial = session.snapshotEvents().find(event => event.type === 'request/header') + if (initial?.type !== 'request/header') throw new Error('missing initial request header') + const active = new Map(initial.data.header.tools?.map(tool => [tool.name, tool])) + const states = [active.get('search')] + const events = session.snapshotEvents() + for (const seq of session.surface.nodes) { + const event = events[seq] + if (event?.type !== 'developer/message') continue + for (const block of event.data.message.content) { + if (block.type === 'tool-addition') { + const source = events[event.data.headerSeq!] + if (source?.type !== 'request/header') throw new Error('missing referenced header') + const tool = source.data.header.tools?.find(tool => tool.name === block.toolName) + if (tool === undefined) throw new Error('missing referenced definition') + active.set(block.toolName, tool) + } + else if (block.type === 'tool-removal') active.delete(block.toolName) + else continue + states.push(active.get('search')) + } + } + return states +} + +describe('developer tool history', () => { + + it.each([false, true])('defers ignorable developer interpretation until catalog completion (known: %s)', (knowsDeveloper) => { + const header = { version: 4, id: 'opaque-developer', createdAt: 1, isSeeded: false, delegationDepth: 0 } + const events: SessionFormatEvent[] = [ + { type: 'developer/message', seq: 0, time: 1, ignorable: true, surfaceOp: { future: true }, data: { + message: { role: 'developer', source: { kind: 'plugin' } }, future: true, + } }, + { type: 'turn/start', seq: 1, time: 2, data: { turn: 1 } }, + { type: 'step/start', seq: 2, time: 3, data: { turn: 1, step: 1 } }, + ] + const known = new Set(events.map(event => event.type)) + if (!knowsDeveloper) known.delete('developer/message') + const catalog = createSessionFormatCatalog({ + ...sessionFormatCatalogOptions, + restoreCurrent: candidate => restoreReleasedV4Artifact(candidate, known), + }) + const reader = catalog.createRestore(sessionFormatCatalog.encodeCurrentHeader(header, 0), { recovery: 'strict', validation: 'current' }) + for (const event of events) reader.decodeRow(event) + if (knowsDeveloper) expect(() => reader.finish()).toThrow() + else expect(reader.finish()).toEqual({ header, events, inheritedEventCount: 0 }) + }) + + it('stores only the activated name in each addition', () => { + expectTypeOf().toEqualTypeOf<{ type: 'tool-addition'; toolName: string; tool?: never }>() + }) + + it('reconstructs remove/re-add and replacement from historical headers after restart and fork', () => { + const parent = Session.create(SessionId('tool-history')) + const initial: ToolSchema = { name: 'search', description: 'Initial', parameters: {} } + const first: ToolSchema = { name: 'search', description: 'First', parameters: { properties: { query: { type: 'string' } } }, deferLoading: true } + const second: ToolSchema = { name: 'search', description: 'Second', parameters: { properties: { limit: { type: 'number' } } } } + const third: ToolSchema = { name: 'search', description: 'Third', parameters: { properties: { exact: { type: 'boolean' } } } } + const expected = structuredClone([initial, first, undefined, second, third]) + const append = (turn: number, tool: ToolSchema) => { + const headerSeq = parent.append('request/header', { reason: 'change', header: { config: { provider: 'test', model: 'test' }, tools: [tool] } }).seq + return parent.append('developer/message', { + turn, step: 1, headerSeq, message: createDeveloperMessage({ source: { kind: 'tool-registry' }, content: [{ type: 'tool-addition', toolName: tool.name }] }), + }, { surfaceOp: 'append' }) + } + parent.append('turn/start', { turn: 1 }) + parent.append('step/start', { turn: 1, step: 1 }) + parent.append('request/header', { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [initial] } }) + append(1, first) + parent.append('developer/message', { turn: 1, step: 1, message: createDeveloperMessage({ + source: { kind: 'tool-registry' }, content: [{ type: 'tool-removal', toolName: 'search' }], + }) }, { surfaceOp: 'append' }) + append(1, second) + parent.append('step/end', { turn: 1, step: 1 }) + const boundary = parent.append('turn/end', { turn: 1, reason: { kind: 'completed' } }).seq + parent.append('turn/start', { turn: 2 }) + parent.append('step/start', { turn: 2, step: 1 }) + append(2, third) + parent.append('step/end', { turn: 2, step: 1 }) + parent.append('turn/end', { turn: 2, reason: { kind: 'completed' } }) + + initial.description = 'mutated initial definition' + first.description = 'mutated producer definition' + first.parameters['properties'] = {} + second.description = 'mutated replacement' + expect(toolStates(parent)).toEqual(expected) + expect(toolStates(restore(parent))).toEqual(expected) + + const childId = SessionId('tool-history-fork') + const child = Session.create(childId, buildForkSeed(parent.snapshotEvents(), boundary), + { ...parent.header, id: childId, parentSession: parent.id, isSeeded: true }, SessionLogOffset(boundary + 1)) + expect(toolStates(restore(child))).toEqual(expected.slice(0, 4)) + }) +}) diff --git a/packages/session/session-format-catalog/tests/preset-migration.spec.ts b/packages/session/session-format-catalog/tests/preset-migration.spec.ts index 74896f7837..08cef8b978 100644 --- a/packages/session/session-format-catalog/tests/preset-migration.spec.ts +++ b/packages/session/session-format-catalog/tests/preset-migration.spec.ts @@ -1,7 +1,8 @@ /** Every historical entry generation migrates all preset selections before projection or fork. */ import { describe, expect, it } from 'vitest' -import { sessionFormatCatalog } from '../src/index.ts' +import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session' +import { createSessionFormatCatalogWithChildren } from '../src/index.ts' describe('catalog preset migration', () => { it.each([0, 1, 2])('migrates a seeded v%i header and every inherited/local selection', (version) => { @@ -18,10 +19,10 @@ describe('catalog preset migration', () => { ? [...rows.slice(0, 2), { type: 'session/end-seed', seq: 2, time: 2, data: { inherited: true } }, ...rows.slice(2)] : rows const before = JSON.stringify({ header, source }) - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) for (const row of source) restore.decodeRow(row) const artifact = restore.finish() - expect(artifact.header).toMatchObject({ version: 3, id: 'code', agentPreset: 'ptc', isSeeded: true }) + expect(artifact.header).toMatchObject({ version: SESSION_FORMAT_VERSION, id: 'code', agentPreset: 'ptc', isSeeded: true }) expect(artifact.inheritedEventCount).toBe(2) expect(artifact.events.map(event => event.seq)).toEqual([0, 1, 2, 3, 4, 5]) expect(artifact.events.filter(event => event.type === 'agent-preset/selected').map(event => event.data)) @@ -30,13 +31,13 @@ describe('catalog preset migration', () => { expect(JSON.stringify({ header, source })).toBe(before) }) - it('does not reinterpret a native v3 custom preset named code', () => { + it('does not reinterpret a V3 custom preset named code', () => { const header = { type: 'session', version: 3, id: 'native', createdAt: 1, isSeeded: false, delegationDepth: 0, agentPreset: 'code', } const row = { type: 'agent-preset/selected', seq: 0, time: 1, data: { agentPreset: 'code' } } - const restore = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) restore.decodeRow(row) expect(restore.finish()).toMatchObject({ header: { agentPreset: 'code' }, events: [row] }) }) diff --git a/packages/session/session-format-catalog/tsconfig.json b/packages/session/session-format-catalog/tsconfig.json index 42a9cc2ff3..0dc8e0c9e9 100644 --- a/packages/session/session-format-catalog/tsconfig.json +++ b/packages/session/session-format-catalog/tsconfig.json @@ -29,6 +29,9 @@ { "path": "../session-format-v2-to-v3" }, + { + "path": "../session-format-v3-to-v4" + }, { "path": "../../compaction/compaction-image-offload" } diff --git a/packages/session/session-format-v2-to-v3/tests/catalog.ts b/packages/session/session-format-v2-to-v3/tests/catalog.ts new file mode 100644 index 0000000000..7541a5d094 --- /dev/null +++ b/packages/session/session-format-v2-to-v3/tests/catalog.ts @@ -0,0 +1,21 @@ +/** Fixed V0–V3 composition for released-edge tests, independent of the current writer. */ + +import { KNOWN_SESSION_EVENT_TYPES } from '@deepseek-ai/dsh-session' +import { createSessionFormatCatalog } from '@deepseek-ai/dsh-session-format' +import { releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, sessionFormatV0ToV1 } from '@deepseek-ai/dsh-session-format-v0-to-v1' +import { releasedV2SessionFormatCodec, sessionFormatV1ToV2 } from '@deepseek-ai/dsh-session-format-v1-to-v2' +import { assertReleasedV3Header, releasedV3SessionFormatCodec, restoreReleasedV3Artifact, sessionFormatV2ToV3 } from '../src/index.ts' + +/** Restore the released V3 result through its complete predecessor chain. */ +export const v3Catalog = createSessionFormatCatalog({ + currentVersion: 3, + codecs: [releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, releasedV2SessionFormatCodec, releasedV3SessionFormatCodec], + currentEncoder: releasedV3SessionFormatCodec, + migrations: [sessionFormatV0ToV1, sessionFormatV1ToV2, sessionFormatV2ToV3], + restoreCurrent: artifact => restoreReleasedV3Artifact(artifact, KNOWN_SESSION_EVENT_TYPES), + restoreTransformedCurrent: artifact => restoreReleasedV3Artifact(artifact, KNOWN_SESSION_EVENT_TYPES), + restoreCurrentHeader(header) { + assertReleasedV3Header(header) + return header + }, +}) diff --git a/packages/session/session-format-v2-to-v3/tests/combined-migration.spec.ts b/packages/session/session-format-v2-to-v3/tests/combined-migration.spec.ts index 42fc9965cf..fbb8db6e84 100644 --- a/packages/session/session-format-v2-to-v3/tests/combined-migration.spec.ts +++ b/packages/session/session-format-v2-to-v3/tests/combined-migration.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { v3Catalog as sessionFormatCatalog } from './catalog.ts' import { SessionFormatEventCollector, SessionFormatUnsupportedMigrationError } from '@deepseek-ai/dsh-session-format' import type { SessionFormatEvent, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' import { releasedV3SessionFormatCodec, restoreReleasedV3Artifact } from '../src/index.ts' diff --git a/packages/session/session-format-v2-to-v3/tests/content-admission.spec.ts b/packages/session/session-format-v2-to-v3/tests/content-admission.spec.ts index d448b449d1..ac6a67a213 100644 --- a/packages/session/session-format-v2-to-v3/tests/content-admission.spec.ts +++ b/packages/session/session-format-v2-to-v3/tests/content-admission.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest' import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' import type { SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' -import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { v3Catalog as sessionFormatCatalog } from './catalog.ts' import { restoreReleasedV3Artifact, sessionFormatV2ToV3 } from '../src/index.ts' const header = { version: 2, id: 'content-admission', createdAt: 1, isSeeded: false, delegationDepth: 0 } diff --git a/packages/session/session-format-v3-to-v4/README.i18n.yaml b/packages/session/session-format-v3-to-v4/README.i18n.yaml new file mode 100644 index 0000000000..892da2ad10 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/README.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/session/session-format-v3-to-v4/README.md +README.md: 2c2d3b4342d68cec5e9a9f94f969a380bbbf15f2 +README.zh.md: a92ae34a73f134253880fec3f931815e067bc344 diff --git a/packages/session/session-format-v3-to-v4/README.md b/packages/session/session-format-v3-to-v4/README.md new file mode 100644 index 0000000000..2c2d3b4342 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/README.md @@ -0,0 +1,348 @@ +--- +description: "Complete V3-to-V4 Session conversion and native admission: tool-role results, producer sources, parent catalogs, preserved references, and refusal." +kind: "package-library" +--- + +# @deepseek-ai/dsh-session-format-v3-to-v4 + +English | [中文](README.zh.md) + +## Summary + +Restore supported released V3 Sessions as V4 without rewriting their stored generation. This page specifies the edge's transformations, preservation, prerequisites, and refusal, then separates native V4 admission. The conversion lifts tool results, renames message sources, and appends missing parent catalog facts. Persistence owns file reads and successor publication; this library owns conversion and target rules. + +## Table of Contents + +- [Use this package](#use-this-package) +- [V3-to-V4 specification](#v3-to-v4-specification) + - [Header and physical framing](#header-and-framing) + - [Tool-result representation](#tool-results) + - [Extension data](#extension-data) + - [Message-source conversion](#message-sources) + - [Parent catalog prerequisites](#parent-catalog) + - [Sequence references and inheritance](#sequence-references) + - [Delivery generations](#delivery-guards) + - [Source audit and refusal](#source-audit) +- [Native V4 admission](#native-v4-admission) + - [Header, messages, and surface metadata](#native-fields) + - [Lifecycle and reference relationships](#native-relationships) + - [Developer changes and deferred schemas](#developer-changes) + - [Fork-generated results](#fork-results) + - [Validation entry points and recovery](#native-recovery) +- [Understand the implementation](#understand-the-implementation) +- [Further Exploration](#further-exploration) +- [Model Experience](#model-experience) +- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work) +- [Dev Note](#dev-note) + +----- + + +## Use this package + +Use the [catalog](../session-format-catalog/README.md) for complete restoration. Direct imports serve catalog assembly and tests; this library has no Cordis mount configuration. Its [public exports](src/index.ts) provide the adjacent migration, the released V3 source codec, the V4 codec, and target validators. The source codec remains owned by [V2-to-V3](../session-format-v2-to-v3/README.md). + +Header-only migration validates and advances metadata without reading the body or collecting children: + +```text +const targetHeader = sessionFormatV3ToV4.migrateHeader(sourceHeader) +``` + +Historical body restoration requires explicit child evidence. `sessionFormatV3ToV4.createStage()` refuses without that binding; an empty array explicitly declares no children. Persistence must collect the complete available direct-child set, while isolated transcript replay can supply its deliberately empty set. Keep the evidence unchanged for the catalog's lifetime. + +```text +const catalog = createSessionFormatCatalogWithChildren(childFacts) +const restore = catalog.createRestore(physicalHeader, { + recovery: 'strict', validation: 'current', +}) +for (const row of physicalRows) restore.decodeRow(row) +const artifact = restore.finish() +``` + +Every restore creates independent Stage state. Compact runs expand as iterables without an intermediate event array. Partial emissions do not establish success: a later row or `finish()` can refuse the artifact. The [format protocol](../session-format/README.md) owns scheduling and error handling; [JSONL persistence](../session-persistence-jsonl/README.md) owns source reads, preparation, and verified exclusive successor publication. + +----- + + +## V3-to-V4 specification + +This edge changes only the named representations below and appends available missing catalog facts. It namespaces unknown ignorable event types and retains each admitted source event's time, sequence, message identities, surface operation, references, and all fields outside those conversions. It creates no system prompt, developer event, tool execution, or replacement message. Earlier V0–V2 inputs first pass through their existing edges to V3; those edges retain their own transformations and refusal policies. + + +### Header and physical framing + +| Input | V4 result | Preservation or refusal | +|---|---|---| +| Logical V3 header | `version: 3` becomes `4` | Released V3 header validation runs first; all other logical header fields remain unchanged. | +| V3 physical rows | Released V3 source codec decodes events and compact runs | Source framing and source-event range decoding remain owned by the preceding package. | +| V4 physical rows | `releasedV4SessionFormatCodec` reuses released V2 framing with native V4 admission | No V4 event is projected into a V3 semantic validator. Encoding and decoding do not run this incoming migration. | + +No preset id, PTC dispatch event tag, file attachment, or physical filename is renamed by this edge. Content extensions in embedded streams follow the rules below; stream order and indices remain unchanged. + + +### Tool-result representation + +[liftToolResult](src/tool-role.ts) converts the message of a `tool/result` event whose source representation has role `user`. It requires a nonempty message id, source `{ kind: 'tool', callId }` with a nonempty call id, and exactly one `tool-result` block naming the same call. The block's content must be an array; an optional `isError` must be boolean. + +| V3 field | V4 field or treatment | +|---|---| +| `data.message.role: 'user'` | `role: 'tool'` | +| `data.message.content[0].toolCallId` | `data.message.toolCallId`, equal to the retained `source.callId` | +| `data.message.content[0].content` | Direct `data.message.content`, including empty content | +| `data.message.content[0].isError` | Optional `data.message.isError` | +| Wrapper `type: 'tool-result'` | Removed with the wrapper | +| Message `id`, `source`, event fields | Retained; no message or call id is minted | + +The wrapper alone supplies the interpreted call id, content, and optional error flag. Other wrapper fields become `plugin:result:`; outer message fields other than `id`, `role`, `source`, and `content` become `plugin:message:`. Complete original names remain in the suffix, including existing prefixes. Distinct owners and colliding names retain separate values; own `__proto__` and `constructor` data stays intact. No metadata container or new content type is added. + +A malformed canonical wrapper raises a format error. Nested results are unsupported by this converter and refuse without publishing a successor. The transformation does not repair contradictory `data.error`; native target validation requires it to accompany the wrapper's `isError: true`. Converter support may expand later while preserving the established native V4 representation. + + +### Extension data + +Unknown V3 content tags become `plugin:`; all other fields remain unchanged and opaque. Stream starts use the same tag in `blockType`; every other field retains its original key and value. An existing prefix on a content tag is prefixed again, keeping distinct old names distinct. Arguments, replay state, and plugin content fields are not traversed. These names do not load or execute plugins. + +Request-tool definitions retain their own field names and values, including ordinary extension metadata. A definition with its own top-level `deferLoading` field refuses V3 migration: the field is defined only in V4, so this edge assigns it no historical meaning. Nested parameter data is unchanged. Native V4 admission of `deferLoading: true` is unchanged. + + +### Message-source conversion + +The [message walker](src/sources.ts) visits only these payload positions. It converts legacy plugin wrappers and retains direct source kinds. + +| Owning event | Message position | +|---|---| +| `user/message` | `data` | +| `system/message`, `assistant/message`, `tool/result` | `data.message` | +| `agent/inbox/spliced` | Each `data.inserted[]` member | +| `session/title-llm-request` | Each `data.messages[]` member | +| `developer/message` | Native walker only; an unknown ignorable V3 event is namespaced and its payload is not visited | + +A plugin source requires a string `plugin`, including the empty string. Conversion removes that property, replaces `kind`, and preserves every other own JSON property. Direct source kinds must be nonempty strings. Conversion does not infer missing metadata from message text, tool arguments, configuration, or current files. + +| Exact V3 `plugin` | V4 `kind` | +|---|---| +| `compact` | `compact-checkpoint` | +| `tools-code-mode`, `tools-ptc` | `ptc-mode` | +| `dsh-compaction-basic` | `compact-basic` | +| `@deepseek-ai/dsh-system-prompt`, on a system-role message | `system-prompt` | +| `@deepseek-ai/dsh-system-prompt`, on another role | `runtime-context` | +| Same-name first-party producers listed below | The exact plugin string | +| Any other plugin name | `plugin:` followed by the complete original name | + +The same-name producers are `agent-instructions`, `session-reference`, `team-message`, `goal`, `skill-invocation`, `skill-catalog`, `coordinator`, `subagent-report`, `subagent-settled`, `webhook`, `agent-message`, `model-selection`, `plan-mode`, `time-context`, `tmux-context`, `user-approval`, `repeat-tool-reminder`, `tool-cordis`, `cordis-host-runner`, `tool-goal`, `tool-jobs`, `hooks-codex`, `hooks-claude-code`, `schedule`, and `dsh-session-title-llm`. + +The complete plugin string is retained after `plugin:`: a plugin named `acme` becomes `plugin:acme`. Direct sources, including unknown and already-prefixed kinds, keep their original kind and every own JSON field. + +There is no recursive source search. Captured request text, assistant replay state and streams, tool arguments/content metadata, Team payloads, and arbitrary nested objects remain unchanged unless another explicitly named rule applies. + + +### Parent catalog prerequisites + +`historicalChildCatalogSource()` collects a direct subagent child's id and creation time, the number of its own `subagent/descriptor` events after its inherited cut, and the first descriptor payload. The child must have `origin: 'subagent'` and a direct parent. Supplemental facts require `childId`, a nonnegative safe-integer `childCreatedAt` and `descriptorCount`, and a `descriptor` property; absent descriptors are represented by null. An optional `sourcePath` is retained for diagnostics. + +| Available evidence | Migration decision | +|---|---| +| One descriptor with version 1 | Require string provider and label; derive `mode: 'continuable'`. | +| One descriptor with version 2 or 3 | Require string provider; use its mode and optional label under catalog rules. | +| Zero descriptors, or an unsupported descriptor version | May retain an existing parent entry; cannot create a missing entry. | +| More than one own descriptor | Retain an existing parent entry without mode/label comparison; do not create a missing entry. | +| Existing own parent entry | Retain it and its extensions; require matching child creation time and mode/label from exactly one supported own descriptor, when available. | +| Missing own parent entry with complete supported evidence | Append a version-0 catalog fact with child id, creation time, mode, and optional label. | +| Missing own parent entry without complete evidence | Preserve the parent without inventing a catalog entry. | + +Catalog version 0 requires string `childId`, nonnegative safe-integer `childCreatedAt`, mode `continuable` or `one-shot`, and a string label for continuable mode; a present one-shot label must also be a string. Duplicate own child ids are refused. Existing entries without a corresponding retained child remain in the parent. Descriptor collection does not restore a child's old continuation composition or recover deleted children from tool arguments. + +The stage considers parent catalog records only after the final inherited cut. Every inherited marker discards earlier catalog candidates without interpreting their payloads. Missing entries append after all source events, sorted by creation time then child id, with dense new sequences. Their time is the final source event's time, or header creation time for an empty log. They neither enter the model surface nor change the inherited count. + +Storage supplies the complete recognizable child set within its root and rechecks membership and physical revisions during preparation, memo reuse, and publication. Incomplete descriptor evidence only prevents that child’s backfill. Unreadable headers that prevent classifying membership, unsupported selected generations, or source drift refuse the operation. The package itself reads no files; [persistence](../session-persistence-jsonl/README.md) owns encoding, locks, cancellation, and publication. + + +### Sequence references and inheritance + +This edge performs no coordinate remapping. Existing event sequences, `sourceEventSeqs`, replacement `startSeq/endSeq`, command and title references, compaction spans, captured Session references, delivery coordinates, turn/step numbers, stream indices, and all ids retain their values. Tool-result lifting and source conversion do not change source event count; appended catalog records only extend the suffix. + +For a seeded Session, the last `session/end-seed` carrying `inherited: true` identifies the inherited event count, excluding that marker. It is unchanged from the V3-stage input, including when preceding V0–V2 migrations already remapped it. A supplied source cut must agree; a missing tagged marker, an inherited marker in an unseeded Session, or a cut outside the events is refused. Unseeded stages expose zero before EOF; seeded stages leave the count unknown until `finish()`. Untagged markers do not define fork inheritance. + + +### Delivery generations + +| Delivery record | Admission and preservation | +|---|---| +| Any interpreted `session-log-deepseek/delivery-accepted` | Generation must be a nonnegative safe integer; omission identifies V0. | +| V3 source marker claiming generation 4 | Refuse: advancing the header must not activate a target-generation watermark. | +| V3 source marker for generation 3 | Require a nonempty Session id and nonnegative safe-integer `throughSeq` before the marker; a foreign id is allowed only before the inherited cut with `parentSession`. | +| Other source generations, including values above 4 | Retain their event type, payload, and coordinates unchanged; they remain inactive in V4. | +| Native V4 marker for generation 4 | Apply the same earlier-coordinate and Session-ownership checks using V4 as current. | +| Native V4 historical marker, including generation 3 | Retain recorded coordinates and identity; it is not a V4 acceptance watermark. | + +No delivery payload or event type is rewritten. Higher-version migrations own any future activation checks; this edge checks only promotion to V4. The marker’s envelope sequence remains unchanged. + + +### Source audit and refusal + +V3 physical decoding and header validation run before the stage. The stage checks dense sequences, source cuts, canonical tool-result wrappers, named plugin sources, delivery ownership, and supplied catalog evidence as specified above. It does not run the complete released V3 semantic restorer or copy the V2→V3 event/content allowlist. Complete restoration additionally applies the V4 target rules below; physical parsing, stage conversion, and target restoration are distinct checks. + +Only the enumerated messages and fields are converted. Unrelated events and arbitrary JSON do not acquire new meanings from matching strings or numbers. The fixed `RELEASED_V3_EVENT_TYPES` set separates source events from extensions independently of the current writer. The stage rejects unknown required V3 event types before interpreting their payloads or consulting the V4 vocabulary, including names that V4 recognizes. Unknown ignorable names become `plugin:` with their payload unchanged. No generic source-schema validation or recursive numeric-field inference is implied. + +Only the canonical V3 `tool/result` wrapper has a preserving conversion. A retired `tool-result` block in another interpreted position is refused by target admission rather than retained as an invalid V4 block. Native V4 applies the same tag refusal before recoverable suffix suppression. The check covers only these positions: + +| Owner | Content inspected for the retired tag | +|---|---| +| `user/message` | `data.content[]` | +| `system/message`, `developer/message`, `assistant/message`, `tool/result` | `data.message.content[]`; the canonical source tool/result wrapper is lifted before target checking | +| `agent/inbox/spliced`, `session/title-llm-request` | `data.inserted[].content[]` and `data.messages[].content[]`, respectively | +| `team/message/queued` | `data.message.content[]` | +| `compaction/summary`, `tool/ptc-dispatch` | `data.summary[]`, optional `data.rawOutput[]`, and `data.content[]`, respectively | +| Embedded assistant streams | `assistant/message.data.stream[]` and `assistant/attempt.data.stream[]` entries with `type: 'chunk'`: `chunk.block.type` for `block-end`, and `chunk.blockType` for `block-start` | + +The [retired-syntax check](src/retired-syntax.ts) examines direct block tags, not arbitrary descendants. Tool arguments, replay state, JSON-schema parameters, nested metadata, and unknown ignorable event payloads remain opaque. An unknown ignorable developer payload is deferred until reader vocabulary recognizes it; the writer validates known developer records even when marked ignorable. + +A direct stage can raise `SessionFormatError` for malformed data or `SessionFormatUnsupportedMigrationError` when a preserving conversion is unavailable. The catalog wraps stage failures as unsupported migration; transformed-target failures receive that classification as well. Strict current validation reports its target failure directly. Physical corruption follows the chosen decoder recovery policy. No prefix is a completed restore, and a refusal does not authorize source mutation, a partial successor, or generation fallback. + +----- + + +## Native V4 admission + +An input already marked V4 never runs V3→V4. Native validation preserves recorded events and returns the same artifact; it does not synthesize catalog entries, fork results, developer changes, or repaired source fields. The following catalog describes the current accepted V4 rules, separately from historical transformations. + + +### Header, messages, and surface metadata + +| Data | Native rule | +|---|---| +| Logical header | Exact required fields `version`, `id`, `createdAt`, `isSeeded`, `delegationDepth`; optional `cwd`, `parentSession`, `origin`, `agentPreset`; no other keys. Version is 4, id is a string, creation time/depth are nonnegative safe integers, seeded is boolean, cwd is absolute when present, optional ids are strings, and origin is `subagent` when present. | +| Event envelope | Required `type`, `seq`, `time`, and JSON `data`; only optional `surfaceOp`, `sourceEventSeqs`, and `ignorable` are admitted. Sequences are dense nonnegative safe integers, time is a safe integer, and a present `ignorable` is exactly true. | +| Surface messages | System, user, developer, assistant, and tool/result require placement and identified messages with their matching role. Installed Session validation owns ordinary message envelopes and role-specific source acceptance. | +| Replacements and references | Endpoints select an inclusive current-surface span in surface order; references name earlier events and cover removed nodes. The protected first system head can be replaced only by one system message covering exactly that head. | +| Request header | Reject retired `header.system`, even empty, and malformed header/data records; installed Session checks current config, reason, adapter-default markers, and omission of empty `tools` / `adapterDefaults`. | +| Tool result | Require role `tool`, nonempty message/call ids, matching `source.kind: 'tool'` and `source.callId`, direct array content, no retired result wrapper, and boolean `isError` when present. `data.error` requires `isError: true`. | +| System message | Require positive turn/step, nonempty id, role `system`, array content, and system-prompt source. Known text/reasoning, tool-call, and image fields are checked; retired tool-result wrappers are refused. Additional JSON metadata and merge-extensible block kinds are not globally stripped. | +| Producer attribution | Interpreted message slots require an object source with a nonempty, non-`plugin` kind. Unknown attribution and own JSON metadata survive; this does not grant a producer runtime authority. | + +All five surface event types require `surfaceOp`. A present `sourceEventSeqs` must be a nonempty array of unique earlier nonnegative safe-integer sequences; `assistant/message` must omit it. Because a replacement must cite all removed nodes, an assistant event cannot itself replace a surface span. Known log-only events carry neither field. A replacement object has exactly `op: 'replace'`, `startSeq`, and `endSeq`; old endpoint names, mixed spellings, and extra keys are refused. + +Request-header config requires nonempty provider/model strings; a present reasoning effort is a nonempty string. `reason` is `initial`, `resume`, `change`, or `series`, and a present `startsSeries` is true. Adapter-default markers use only `reasoningEffort` and `maxTokens`, each set to true with its corresponding config value present. These checks do not execute arbitrary tool JSON schemas. + +System image admission requires a nonempty attachment id, one of PNG/JPEG/WebP/GIF MIME types, nonnegative bytes, positive width/height, optional string name, and positive original dimensions when present. Native storage admission is distinct from whether a particular model provider can represent that content. + +Current common admission does not validate each user/tool/developer content block against the complete generated schema. It checks message identity, role, source, and an array container; version-specific validators add only the checks listed here. Unknown block kinds and uninspected fields can therefore survive storage admission and still be refused by a provider. + + +### Lifecycle and reference relationships + +| Owner | Required relationship | +|---|---| +| `turn/start`, `turn/end`, `step/start`, `step/end` | Ordered turn/step numbers, matching open owners, no overlapping turn/step, and no unresolved advertised or started tool call at a closing boundary. Unfinished tails remain open. | +| `assistant/message`, `tool/call`, appended `tool/result` | Match an open step; advertised call ids are unique, starts retain name/arguments, and results settle one advertised call. A result before its start requires the exact admitted `TOOL_NOT_STARTED` repair. Tool-result surface replacements require an open turn instead of replaying the original call lifecycle. | +| `system/message`, `developer/message`, `assistant/attempt` | Match an open turn and step. Request headers and contexts require an open turn. | +| `tool/ptc-dispatch-start`, `tool/ptc-dispatch` | Require an open turn, unique sub-call start and settlement, stable root/parent/name/arguments, and a nested parent belonging to the same root. | +| `llm/retry`, `llm/retry-started` | Match the current request provider and turn/step, sequential attempts per policy chain, stable retry identity, and one start matching a prior scheduled attempt. | +| `session/title`, `session/title-llm-request` | Cite distinct earlier human `user/message` events. User-assigned titles have no citations; other titles have citations. An LLM title request has nonempty citations and one user-role text message sourced from `dsh-session-title-llm`. | +| `command/run`, `command/done` | Run ids are unique; completion has a prior run. A present completion `sourceEventSeq` names an earlier non-command event and accompanies success. | +| `compaction/start`, `compaction/summary`, `compaction/end` | Match compaction id, source command, and the active turn context. Summary spans name exact current-surface nodes and exclude the protected head; successful completion has one summary. Inherited unfinished compactions expire at the end-seed marker. | +| `compaction/prune` | Its span names exact current-surface nodes and excludes the protected head; it does not require a compaction transaction or its owner fields. | +| Compact checkpoint replacement | Its `compact-checkpoint` source identifies the active compaction. | +| Native `subagent/catalog` | Check own version-0 payload fields and unique child ids after the inherited cut. Native reads neither collect child logs nor compare their physical facts; inherited entries do not establish own membership. | +| Inherited cut and delivery | Apply the marker, coordinate, and generation-ownership rules stated above. | + +These checks are generation-owned in [relationships.ts](src/relationships.ts). Full common message/envelope acceptance and plugin-owned message projections additionally use the installed Session; the exported V4 restorer alone is not a replacement for complete catalog restoration. + + +### Developer changes and deferred schemas + +The edge does not create developer history. Native `developer/message` requires positive turn/step coordinates, role `developer`, a nonempty message id, array content, and producer-owned source metadata. Each `tool-addition` or `tool-removal` block requires a nonempty `toolName`. Additions reject any own inline `tool` field, including values that would otherwise be optional JSON metadata. + +An event containing additions must have `headerSeq`; it selects an earlier known `request/header` for all additions in that event. Each name must match exactly one definition there with string `description` and object `parameters`. Missing, forward, wrong-type, unknown, ambiguous, and incomplete bindings are refused. Events without additions must omit `headerSeq`; `sourceEventSeqs` remains independent derivation/replacement metadata. Replacement, fork, restart, and compaction retain the recorded binding rather than consulting the current registry or latest header. + +Tool-change blocks in ordinary messages, inbox/title input, compaction summary/raw output, or embedded assistant block-start/block-end records are refused. A present `request/header.header.tools[].deferLoading` must be exactly true; it is independent of whether any developer addition exists. Empty developer nodes retain surface positions, produce no model message, and cannot replace the protected system head. Unknown ignorable developer payloads are deferred until the reader knows that event type. + +Native format support does not enable automatic emission, provider tool loading, or UI rendering. Current provider and UI consumers explicitly refuse developer history they cannot represent. Backward-compatible consumer support for the already accepted representation is separate from adding a new format. + + +### Fork-generated results + +Fork seed construction belongs to core Session, not this migration. Native V4 admits its synthetic `TOOL_NOT_STARTED` error results with ids `forked-tool-result--`, role `tool`, matching source/call ids, `isError: true`, `ToolNotStartedError`, and one text block. Append results carry their own sequence and no source references; later replacements retain an earlier suffix and cite exactly that original result. The branch-specific text is retained, not normalized to crash-recovery wording. + +Started fork calls use `TOOL_OUTCOME_UNKNOWN` error results and retain their recorded start references. They follow ordinary started-call validation; the special not-started identity rules above do not apply to them. Fork construction closes its open tail with `turn/end.reason.kind: 'forked'` and leaves completed earlier steps and turns unchanged. + +The ordinary interrupted not-started repair retains its canonical historical integer suffix and exact crash-recovery text. Both forms must settle an advertised call under the lifecycle rules. The stage preserves existing fork/call/message ids; it does not infer ancestry from their string prefixes or execute a tool. + + +### Validation entry points and recovery + +| Entry point | Checks and limits | +|---|---| +| V4 codec decode | Released physical framing plus V4 row admission. Required predecessor PTC tags, retired system headers, and owned malformed native fields are refused before recoverable suffix suppression. | +| V4 codec encode | The same native row checks; ignorable developer payloads are still validated by the writer. | +| Native catalog, `validation: 'transformed'` | Codec checks only; skips artifact restoration because no migration ran. This is not full native validation. | +| Historical catalog, `validation: 'transformed'` | Conversion followed by generation-owned V4 restoration; skips installed common Session validation. | +| Catalog, `validation: 'current'` | Generation-owned V4 checks plus installed current Session header, envelope, message, surface, and projection validation. Use strict recovery for fixtures and publication verification. | +| Native JSONL scanner | Supplies installed vocabulary to row admission before recovery and applies mandatory V4 relationships before exposing the accepted prefix. | + +Unknown required events are refused by vocabulary-aware restoration. Unknown ignorable payloads remain uninterpreted; required `tool/code-dispatch-start` / `tool/code-dispatch` are refused as retired syntax, while ignorable predecessors stay opaque. The physical decoder defers ignorable developer payloads when vocabulary is absent; a native reader that knows developer events must validate them before accepting a recoverable suffix. Only accepted inherited markers establish the cut. + +----- + + +## Understand the implementation + +
+Implementation internals — click to expand + +The migration declaration creates independent streaming stages. Compact runs expand as iterables without an intermediate event array. The V3-to-V4 stage rewrites historical message sources and lifts historical tool-result wrappers once while emitting V4 events. The V4 codec uses the released V2 codec only for physical header and source-range framing, and validates native tool-role rows directly; it does not invoke the released V3 validator or source-conversion views. JSONL scanners call `assertV4RowAdmission` before suppressing recoverable rows and the shared mandatory relationship validator before returning the completed logical prefix. + +The target restorer validates native fields and mandatory cross-event relationships, then returns the original artifact. Unknown ignorable events remain opaque, and unfinished inherited compactions expire at the end-seed marker. No runtime invariant companion is published because this pure library owns no independently maintained runtime observations. + +
+ +----- + + +## Further Exploration + +- [Format version and release status](../../../docs/session-format-status.md) — checkout writer and published format authority. +- [Adding a Session format version](../../../docs/cookbook/adding-a-session-format-version.md) — adjacent-edge integration and validation. +- [JSONL persistence](../session-persistence-jsonl/README.md) — immutable generation selection and publication. + +----- + + +## Model Experience + +### Historical restoration + +#### What the model sees + +Historical requests retain their recorded messages and model configuration. The [migration stage](src/migration.ts) represents `tool/result` payloads as tool-role messages without adding model-visible content; catalog records do not enter model messages directly, though later subagent listing can discover the historical children. + +#### Token effect + +The conversion changes no request text or token-bearing data. + +#### KV Cache effect + +The edge preserves the recorded request prefix. Provider cache availability and eviction remain outside this library. + +## Known Limitations and Deferred Work + + + +- **Historical converter coverage** — Unsupported source forms may fail without publishing a successor or changing the source. First-party recordings do not enumerate third-party extensions. Later converter fixes may add support after V4 publication if their V4 output remains compatible. Interpreting extra stream-start fields and preparing future delivery generations require a concrete format change. +- **Accepted V4 transition** — the [checkpoint](../../../docs/session-format-status.md#finalization-record) protects the accepted history. Backward-compatible additions can remain V4 through new acknowledgements; breaking changes require a successor. Already-written V4 files do not rerun this incoming edge, and historical inputs remain intact. +- **V5 prerequisite readers** — V4 child evidence currently goes through the installed catalog. A future writer must bind fixed-generation V4 prerequisite reading before changing that catalog. The exported V4 restorer supplies generation-owned checks; full common message admission additionally uses installed Session validation. +- **Nested historical tool results** — migration currently refuses results containing another tool-result wrapper. The original generation remains intact and no V4 successor is published. A later converter may support evidenced source cases without changing the established V4 format; the [migration cookbook](../../../docs/cookbook/adding-a-session-format-version.md#stages-and-validation) defines that distinction. +- **Historical extension consumers** — prefixed message and result fields preserve JSON data without activating core fields. A consumer must explicitly understand those fields before interpreting them. +- **Retained child logs required** — a parent alone cannot recover unrecorded child ids, creation times, or descriptors. Deleted children cannot be reconstructed from tool arguments; existing parent catalog records remain. +- **Missing historical catalog entries** — without exactly one supported own descriptor, an absent parent entry is not backfilled. The child log remains readable by id; current V4 reads do not rescan children to repair that omission. +- **Storage scope** — facts cover recognizable children within the same persistence root. Cross-root import and corrupt-log repair are outside this migration. + + +### Dev Note + +
+Working context for maintainers — click to expand + +None. + +
diff --git a/packages/session/session-format-v3-to-v4/README.zh.md b/packages/session/session-format-v3-to-v4/README.zh.md new file mode 100644 index 0000000000..a92ae34a73 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/README.zh.md @@ -0,0 +1,348 @@ +--- +description: "完整的 V3 到 V4 Session 转换与原生接纳:工具角色结果、生产者来源、父目录、引用保留及拒绝规则。" +kind: "package-library" +--- + +# @deepseek-ai/dsh-session-format-v3-to-v4 + +[English](README.md) | 中文 + +## 概述 + +在不改写已存储代际的前提下,将受支持的已发布 V3 Session 恢复为 V4。本页完整说明迁移边的转换、保留、前置证据与拒绝规则,再单独说明原生 V4 接纳。转换提升工具结果、重命名消息来源,并追加缺失的父目录事实。持久化层负责文件读取和后继代际发布;本库负责转换与目标规则。 + +## 目录 + +- [使用本包](#use-this-package) +- [V3 到 V4 规范](#v3-to-v4-specification) + - [Header 与物理分帧](#header-and-framing) + - [工具结果表示](#tool-results) + - [扩展数据](#extension-data) + - [消息来源转换](#message-sources) + - [父目录前置证据](#parent-catalog) + - [序号引用与继承](#sequence-references) + - [Delivery 代际](#delivery-guards) + - [源审计与拒绝](#source-audit) +- [原生 V4 接纳](#native-v4-admission) + - [Header、消息与表面元数据](#native-fields) + - [生命周期与引用关系](#native-relationships) + - [Developer 变更与延迟 schema](#developer-changes) + - [Fork 生成的结果](#fork-results) + - [校验入口与恢复](#native-recovery) +- [理解实现](#understand-the-implementation) +- [进一步阅读](#further-exploration) +- [模型体验](#model-experience) +- [已知限制与待办工作](#known-limitations-and-deferred-work) +- [开发备注](#dev-note) + +----- + + +## 使用本包 + +通过 [catalog](../session-format-catalog/README.zh.md) 完成恢复。直接导入用于 catalog 组装和测试;本库没有 Cordis 挂载配置。[公开导出](src/index.ts)提供相邻迁移、已发布的 V3 源 codec、V4 codec 和目标校验器。源 codec 仍由 [V2 到 V3](../session-format-v2-to-v3/README.zh.md) 所有。 + +仅 header 迁移会校验并推进元数据,不读取正文或收集子 Session: + +```text +const targetHeader = sessionFormatV3ToV4.migrateHeader(sourceHeader) +``` + +历史正文恢复要求显式的子级证据。没有该绑定时,`sessionFormatV3ToV4.createStage()` 会拒绝;空数组明确声明没有子级。持久化层必须收集完整的可用直属子级集合,而隔离的 transcript 回放可以提供其刻意为空的集合。Catalog 存续期间,证据必须保持不变。 + +```text +const catalog = createSessionFormatCatalogWithChildren(childFacts) +const restore = catalog.createRestore(physicalHeader, { + recovery: 'strict', validation: 'current', +}) +for (const row of physicalRows) restore.decodeRow(row) +const artifact = restore.finish() +``` + +每次恢复都创建独立的 Stage 状态。紧凑 run 以迭代器展开,不物化中间事件数组。部分输出不代表成功:后续行或 `finish()` 仍可拒绝整份产物。[格式协议](../session-format/README.zh.md)负责调度和错误处理;[JSONL 持久化](../session-persistence-jsonl/README.zh.md)负责源读取、准备以及经验证的独占后继发布。 + +----- + + +## V3 到 V4 规范 + +本边只改变下列明确命名的表示,并追加证据完整的缺失目录事实。未知可忽略事件的类型获得命名空间;每个获准源事件的 time、sequence、消息身份、表面操作、引用以及转换之外的字段均保留。它不创建 system prompt、developer 事件、工具执行或替换消息。更早的 V0–V2 输入先经过各自现有迁移边到达 V3;那些边保留自身的转换与拒绝策略。 + + +### Header 与物理分帧 + +| 输入 | V4 结果 | 保留或拒绝 | +|---|---|---| +| 逻辑 V3 header | `version: 3` 变为 `4` | 先执行已发布 V3 header 校验;其他逻辑 header 字段均不变。 | +| V3 物理行 | 已发布 V3 源 codec 解码事件与紧凑 run | 源分帧和源事件区间解码仍归前一个包所有。 | +| V4 物理行 | `releasedV4SessionFormatCodec` 复用已发布 V2 分帧并执行原生 V4 接纳 | 不把 V4 事件投影到 V3 语义校验器。编码和解码不运行此入边迁移。 | + +本边不重命名 preset id、PTC dispatch 事件标签、文件附件或物理文件名。内嵌流中的内容扩展遵循下列规则,流顺序和索引保持不变。 + + +### 工具结果表示 + +[liftToolResult](src/tool-role.ts) 转换 `tool/result` 事件中源表示为 user 角色的消息。它要求非空消息 id、带非空 call id 的 `{ kind: 'tool', callId }` 来源,以及恰好一个引用同一调用的 `tool-result` block。该 block 的 content 必须为数组;可选 `isError` 必须为布尔值。 + +| V3 字段 | V4 字段或处理 | +|---|---| +| `data.message.role: 'user'` | `role: 'tool'` | +| `data.message.content[0].toolCallId` | `data.message.toolCallId`,等于保留的 `source.callId` | +| `data.message.content[0].content` | 直接作为 `data.message.content`,包括空内容 | +| `data.message.content[0].isError` | 可选的 `data.message.isError` | +| Wrapper 的 `type: 'tool-result'` | 随 wrapper 移除 | +| 消息 `id`、`source` 和事件字段 | 保留;不生成新的消息或调用 id | + +只有 wrapper 提供具有解释语义的调用 id、content 和可选错误标志。Wrapper 的其他字段变为 `plugin:result:<原字段名>`;外层消息除 `id`、`role`、`source` 和 `content` 外的字段变为 `plugin:message:<原字段名>`。后缀保留完整原名称,包括已有前缀。不同 owner 与重名字段分别保留值;`__proto__` 和 `constructor` 的自有数据保持完整。不添加 metadata 容器或新的内容类型。 + +格式错误的 canonical wrapper 引发格式错误。当前转换器不支持嵌套结果,遇到时拒绝且不发布 successor。转换不会修复矛盾的 `data.error`;原生目标校验要求它与 wrapper 的 `isError: true` 同时出现。后续可以扩展转换器支持范围,同时保持既定的原生 V4 表示。 + + +### 扩展数据 + +V3 未知内容标签变为 `plugin:`,其他字段原样保留且不作解释。流起始块的 `blockType` 使用相同标签,其他字段的原始键和值均保留。内容标签的已有前缀会再次添加,使不同旧名称保持不同。不遍历实参、回放状态和插件内容字段。这些名称不会加载或执行插件。 + +请求工具定义保留自有字段的原始名称和值,包括普通扩展元数据。若定义拥有顶层 `deferLoading` 字段,则拒绝 V3 迁移:该字段仅在 V4 中定义,因此本迁移边不为它赋予历史含义。嵌套参数数据保持不变。原生 V4 对 `deferLoading: true` 的接纳规则不变。 + + +### 消息来源转换 + +[消息遍历器](src/sources.ts) 只访问下列 payload 位置。它转换旧插件包装,并保留直接来源 kind。 + +| 所属事件 | 消息位置 | +|---|---| +| `user/message` | `data` | +| `system/message`、`assistant/message`、`tool/result` | `data.message` | +| `agent/inbox/spliced` | 每个 `data.inserted[]` 成员 | +| `session/title-llm-request` | 每个 `data.messages[]` 成员 | +| `developer/message` | 仅由原生遍历器处理;未知可忽略 V3 事件被命名空间化,其 payload 不被访问 | + +插件来源要求字符串 `plugin`,允许空字符串。转换移除该属性、替换 `kind`,并保留其他所有自有 JSON 属性。直接来源 kind 必须为非空字符串。转换不从消息文本、工具参数、配置或当前文件推断缺失元数据。 + +| 精确的 V3 `plugin` | V4 `kind` | +|---|---| +| `compact` | `compact-checkpoint` | +| `tools-code-mode`、`tools-ptc` | `ptc-mode` | +| `dsh-compaction-basic` | `compact-basic` | +| system 角色消息中的 `@deepseek-ai/dsh-system-prompt` | `system-prompt` | +| 其他角色中的 `@deepseek-ai/dsh-system-prompt` | `runtime-context` | +| 下文列出的同名第一方生产者 | 精确的 plugin 字符串 | +| 其他任何插件名 | `plugin:` 后接完整的原始名称 | + +同名生产者为 `agent-instructions`、`session-reference`、`team-message`、`goal`、`skill-invocation`、`skill-catalog`、`coordinator`、`subagent-report`、`subagent-settled`、`webhook`、`agent-message`、`model-selection`、`plan-mode`、`time-context`、`tmux-context`、`user-approval`、`repeat-tool-reminder`、`tool-cordis`、`cordis-host-runner`、`tool-goal`、`tool-jobs`、`hooks-codex`、`hooks-claude-code`、`schedule` 和 `dsh-session-title-llm`。 + +完整的插件字符串保留在 `plugin:` 之后:名为 `acme` 的插件变为 `plugin:acme`。直接来源保留原 kind 和每个自有 JSON 字段,包括未知或已有前缀的 kind。 + +来源查找不递归进行。捕获的请求文本、assistant 回放状态与流、工具参数/内容元数据、Team 载荷以及任意嵌套对象均保留,除非另有明确命名的规则适用。 + + +### 父目录前置证据 + +`historicalChildCatalogSource()` 收集直属 subagent 子 Session 的 id、创建时间、继承截点之后自身的 `subagent/descriptor` 事件数量,以及首个 descriptor 载荷。子 Session 必须带有 `origin: 'subagent'` 和直接父级。补充事实要求 `childId`、非负安全整数 `childCreatedAt` 与 `descriptorCount`,以及 `descriptor` 属性;缺失的 descriptor 用 null 表示。可选 `sourcePath` 用于诊断。 + +| 可用证据 | 迁移决定 | +|---|---| +| 一个 version 1 descriptor | 要求字符串 provider 与 label;导出 `mode: 'continuable'`。 | +| 一个 version 2 或 3 descriptor | 要求字符串 provider;按目录规则使用其 mode 和可选 label。 | +| 没有 descriptor,或 descriptor 版本不受支持 | 可以保留已有父目录项;不能创建缺失项。 | +| 多个自身 descriptor | 保留已有父目录项,不比较 mode/label;不创建缺失项。 | +| 已有自身父目录项 | 保留条目及其扩展;要求子创建时间一致,并在恰好一个受支持的自身 descriptor 可用时比较其 mode/label。 | +| 缺少自身父目录项,且受支持证据完整 | 追加带 child id、创建时间、mode 和可选 label 的 version-0 目录事实。 | +| 缺少自身父目录项,且证据不完整 | 保留父 Session,不凭空创建目录项。 | + +Catalog version 0 要求字符串 `childId`、非负安全整数 `childCreatedAt`、`continuable` 或 `one-shot` mode,以及 continuable mode 下的字符串 label;存在的 one-shot label 也必须是字符串。重复的自身 child id 被拒绝。没有对应保留子日志的已有条目仍保留在父日志中。Descriptor 收集不恢复子级的旧 continuation composition,也不从工具参数恢复已删除子级。 + +Stage 只把最终继承截点之后的父目录记录作为候选。每个 inherited marker 都会丢弃更早的目录候选,不解释其载荷。缺失项追加在所有源事件之后,按创建时间、child id 排序,并使用连续的新序号。时间取最后一个源事件的 time;空日志则取 header 创建时间。这些记录既不进入模型表面,也不改变继承计数。 + +存储层提供其根目录内完整的可识别子级集合,并在准备、复用 memo 与发布时复查成员及物理版本。不完整的 descriptor 证据只阻止补填对应子 Session 的目录项。无法据此判断成员关系的不可读 header、不受支持的所选代际或源变化都会拒绝操作。本包不读取文件;[持久化层](../session-persistence-jsonl/README.zh.md)负责编码、锁、取消与发布。 + + +### 序号引用与继承 + +本边不重映射坐标。已有事件序号、`sourceEventSeqs`、替换端点 `startSeq/endSeq`、command 与 title 引用、compaction 区间、捕获的 Session 引用、delivery 坐标、turn/step 编号、stream 索引以及所有 id 均保留。工具结果提升与来源转换不改变源事件数量;追加的目录记录只扩展后缀。 + +对于 seeded Session,最后一个携带 `inherited: true` 的 `session/end-seed` 确定继承事件数量,且不计该 marker。本边保留 V3 Stage 输入中的该数值,即使先前 V0–V2 迁移已对其重映射。传入的源截点必须一致;缺少 tagged marker、unseeded Session 含 inherited marker、或截点超出事件范围时拒绝。Unseeded Stage 在 EOF 前公开零;seeded Stage 到 `finish()` 才确定计数。Untagged marker 不定义 fork 继承。 + + +### Delivery 代际 + +| Delivery 记录 | 接纳与保留 | +|---|---| +| 任何被解释的 `session-log-deepseek/delivery-accepted` | 代际必须为非负安全整数;省略表示 V0。 | +| V3 源 marker 声明 generation 4 | 拒绝:提升 header 不得激活目标代际的 watermark。 | +| generation 3 的 V3 源 marker | 要求非空 Session id 和早于 marker 的非负安全整数 `throughSeq`;只有在继承截点之前且带 `parentSession` 时才允许其他 Session id。 | +| 其他源代际,包括高于 4 的值 | 原样保留事件类型、payload 与坐标;它们在 V4 中仍未激活。 | +| generation 4 的原生 V4 marker | 以 V4 为当前代际,应用同样的较早坐标和 Session 归属检查。 | +| 原生 V4 中的历史 marker,包括 generation 3 | 保留记录的坐标与身份;它不是 V4 接纳 watermark。 | + +不改写投递 payload 或事件类型。未来的激活检查归对应的更高版本迁移所有,本边只检查向 V4 的提升。标记的信封序号保持不变。 + + +### 源审计与拒绝 + +Stage 之前先执行 V3 物理解码与 header 校验。Stage 按上述规范检查连续序号、源截点、canonical 工具结果 wrapper、命名的 plugin 来源、delivery 归属及传入的目录证据。它不运行完整的已发布 V3 语义恢复器,也不复制 V2→V3 的事件/内容允许列表。完整恢复还会应用下述 V4 目标规则;物理解析、Stage 转换与目标恢复是不同的检查。 + +只转换列明的消息及字段。无关事件及任意 JSON 不会因字符串或数字匹配而获得新含义。固定的 `RELEASED_V3_EVENT_TYPES` 集合独立于当前 writer 区分源事件和扩展。Stage 在解释载荷或查询 V4 词汇之前拒绝 V3 未知必需事件,包括 V4 已认识的名称。未知可忽略事件名称变为 `plugin:`,载荷不变。不隐含通用源 schema 校验或递归数字字段推断。 + +只有 canonical V3 `tool/result` wrapper 具有保留信息的转换。其他被解释位置中的已退役 `tool-result` block 由目标接纳拒绝,不作为无效 V4 block 保留。原生 V4 在 recoverable 后缀抑制前应用同样的标签拒绝。检查只覆盖以下位置: + +| 所有者 | 检查退役标签的内容 | +|---|---| +| `user/message` | `data.content[]` | +| `system/message`、`developer/message`、`assistant/message`、`tool/result` | `data.message.content[]`;canonical 源 tool/result wrapper 在目标检查前已提升 | +| `agent/inbox/spliced`、`session/title-llm-request` | 分别为 `data.inserted[].content[]` 与 `data.messages[].content[]` | +| `team/message/queued` | `data.message.content[]` | +| `compaction/summary`、`tool/ptc-dispatch` | 分别为 `data.summary[]`、可选 `data.rawOutput[]` 与 `data.content[]` | +| 内嵌 assistant 流 | `assistant/message.data.stream[]` 和 `assistant/attempt.data.stream[]` 中 `type: 'chunk'` 的条目:`block-end` 的 `chunk.block.type`,以及 `block-start` 的 `chunk.blockType` | + +[退役语法检查](src/retired-syntax.ts)只检查直接 block 标签,不遍历任意后代。工具参数、回放状态、JSON-schema parameters、嵌套元数据及未知 ignorable 事件载荷保持不透明。未知 ignorable developer 载荷推迟到读取器词汇表识别它时检查;writer 即使给已知 developer 记录标上 ignorable,也会校验它。 + +直接 Stage 可对格式错误的数据抛出 `SessionFormatError`,或在无法保留信息地转换时抛出 `SessionFormatUnsupportedMigrationError`。Catalog 把 Stage 失败包装为不支持迁移;transformed 目标校验失败也使用该分类。Strict current 校验直接报告目标失败。物理损坏遵循所选 decoder 恢复策略。任何前缀都不构成完成的恢复,拒绝也不授权修改源、发布部分后继或回退代际。 + +----- + + +## 原生 V4 接纳 + +已经标记为 V4 的输入从不运行 V3→V4。原生校验保留记录的事件并返回同一产物;它不合成目录项、fork 结果、developer 变更或修复后的源字段。以下目录说明当前已接受 V4 规则,与历史转换分开。 + + +### Header、消息与表面元数据 + +| 数据 | 原生规则 | +|---|---| +| 逻辑 header | 精确的必需字段 `version`、`id`、`createdAt`、`isSeeded`、`delegationDepth`;可选字段 `cwd`、`parentSession`、`origin`、`agentPreset`;无其他键。Version 为 4,id 为字符串,创建时间/深度为非负安全整数,seeded 为布尔值,存在的 cwd 为绝对路径,可选 id 为字符串,存在的 origin 为 `subagent`。 | +| 事件信封 | 必需字段为 `type`、`seq`、`time` 和 JSON `data`;只允许可选的 `surfaceOp`、`sourceEventSeqs` 与 `ignorable`。序号为连续的非负安全整数,time 为安全整数,存在的 `ignorable` 必须恰好为 true。 | +| 表面消息 | System、user、developer、assistant 和 tool/result 要求 placement,以及身份明确且角色匹配的消息。普通消息信封及角色专用来源接纳由已安装 Session 校验负责。 | +| 替换与引用 | 端点按当前表面顺序选择包含两端的区间;引用指向更早事件并覆盖移除节点。受保护的首个 system head 只能由恰好覆盖该 head 的单个 system 消息替换。 | +| Request header | 拒绝已退役的 `header.system`(包括空值)及格式错误的 header/data 记录;已安装 Session 检查当前 config、reason、adapter-default 标记,并要求省略空 `tools` / `adapterDefaults`。 | +| 工具结果 | 要求 tool 角色、非空消息/调用 id、匹配的 `source.kind: 'tool'` 与 `source.callId`、直接数组 content、不含已退役结果 wrapper,以及存在时为布尔值的 `isError`。`data.error` 要求 `isError: true`。 | +| System 消息 | 要求正 turn/step、非空 id、system 角色、数组 content 和 system-prompt 来源。检查已知 text/reasoning、tool-call 及 image 字段;拒绝已退役 tool-result wrapper。额外 JSON 元数据及可通过合并扩展的 block kind 不会被全局删除。 | +| 生产者归属 | 被解释的消息槽要求对象 source,以及非空且不是 `plugin` 的 kind。未知归属和自有 JSON 元数据保留;这不授予生产者运行时权限。 | + +五种表面事件都要求 `surfaceOp`。存在的 `sourceEventSeqs` 必须是非空数组,包含互异、更早、非负的安全整数序号;`assistant/message` 必须省略它。由于替换必须引用全部移除节点,assistant 事件自身不能替换表面区间。已知纯日志事件不能携带任一字段。替换对象只能包含 `op: 'replace'`、`startSeq` 与 `endSeq`;旧端点名、混合写法及额外键均被拒绝。 + +Request-header config 要求非空 provider/model 字符串;存在的 reasoning effort 为非空字符串。`reason` 为 `initial`、`resume`、`change` 或 `series`,存在的 `startsSeries` 为 true。Adapter-default 标记只能使用 `reasoningEffort` 与 `maxTokens`,值均为 true,且对应 config 值必须存在。这些检查不执行任意工具 JSON schema。 + +System image 接纳要求非空 attachment id、PNG/JPEG/WebP/GIF MIME 类型之一、非负 bytes、正 width/height、可选字符串 name,以及存在时为正的原始尺寸。原生存储接纳与具体模型提供方能否表示该内容是不同的问题。 + +当前通用接纳不会按完整的生成 schema 校验每个 user/tool/developer content block。它检查消息身份、角色、来源与数组容器;代际专用校验器只增加此处列出的检查。因此,未知 block kind 和未检查的字段可能通过存储接纳,但仍被提供方拒绝。 + + +### 生命周期与引用关系 + +| 所有者 | 必需关系 | +|---|---| +| `turn/start`、`turn/end`、`step/start`、`step/end` | Turn/step 编号有序,开放所有者匹配,turn/step 不重叠,结束边界不遗留已声明或已开始但未解决的工具调用。未完成尾部保持开放。 | +| `assistant/message`、`tool/call`、追加的 `tool/result` | 匹配开放 step;声明的调用 id 唯一,开始保留 name/arguments,结果结算一个已声明调用。开始之前的结果必须是精确获准的 `TOOL_NOT_STARTED` 修复。工具结果的表面替换要求开放 turn,不重放原始调用生命周期。 | +| `system/message`、`developer/message`、`assistant/attempt` | 匹配开放 turn 与 step。Request header 和 context 要求开放 turn。 | +| `tool/ptc-dispatch-start`、`tool/ptc-dispatch` | 要求开放 turn、唯一 sub-call 开始与结算、稳定的 root/parent/name/arguments,以及属于同一 root 的嵌套 parent。 | +| `llm/retry`、`llm/retry-started` | 匹配当前请求 provider 和 turn/step,每条策略链的尝试连续、retry 身份稳定,每次 start 匹配一个先前已调度的尝试。 | +| `session/title`、`session/title-llm-request` | 引用互异且更早的真人 `user/message` 事件。用户指定标题没有引用;其他标题具有引用。LLM 标题请求带非空引用和一个来源为 `dsh-session-title-llm` 的 user 角色文本消息。 | +| `command/run`、`command/done` | Run id 唯一;完成记录对应先前 run。存在的完成 `sourceEventSeq` 引用更早的非 command 事件,并伴随 success。 | +| `compaction/start`、`compaction/summary`、`compaction/end` | 匹配 compaction id、源 command 和活动 turn 上下文。Summary 区间引用精确的当前表面节点且排除 protected head;成功完成需要一个 summary。继承的未完成 compaction 在 end-seed marker 处过期。 | +| `compaction/prune` | 其区间引用精确的当前表面节点且排除 protected head;它不要求存在 compaction 事务或其所有者字段。 | +| Compact checkpoint 替换 | 其 `compact-checkpoint` 来源标识活动 compaction。 | +| 原生 `subagent/catalog` | 检查继承截点之后的自身 version-0 载荷字段与 child id 唯一性。原生读取既不收集子日志,也不比较其物理事实;继承项不建立自身成员关系。 | +| 继承截点与 delivery | 应用上文的 marker、坐标及代际归属规则。 | + +这些检查由 [relationships.ts](src/relationships.ts) 按代际拥有。完整的通用消息/信封接纳与插件拥有的消息投影还使用已安装 Session;单独的导出 V4 恢复器不能替代完整 catalog 恢复。 + + +### Developer 变更与延迟 schema + +本边不创建 developer 历史。原生 `developer/message` 要求正 turn/step 坐标、developer 角色、非空消息 id、数组 content,以及生产者拥有的来源元数据。每个 `tool-addition` 或 `tool-removal` block 都要求非空 `toolName`。添加块拒绝任何自有内嵌 `tool` 字段,包括其他情况下可作为可选 JSON 元数据的值。 + +含有添加块的事件必须带 `headerSeq`,为该事件内全部添加选择一个更早且已知的 `request/header`。每个名称必须在那里恰好匹配一个带字符串 `description` 和对象 `parameters` 的定义。缺失、前向、错误类型、未知、歧义或不完整的绑定均被拒绝。没有添加块的事件必须省略 `headerSeq`;`sourceEventSeqs` 仍是独立的派生/替换元数据。替换、fork、重启和 compaction 保留记录的绑定,不查询当前 registry 或最新 header。 + +普通消息、inbox/title 输入、compaction summary/raw output 以及内嵌 assistant block-start/block-end 记录中的工具变更块均被拒绝。存在的 `request/header.header.tools[].deferLoading` 必须恰好为 true;它与是否存在 developer 添加事件无关。空 developer 节点保留表面位置,不产生模型消息,也不能替换 protected system head。未知 ignorable developer 载荷推迟到读取器知道该事件类型时校验。 + +原生格式支持不启用自动发出、提供方工具加载或 UI 渲染。当前提供方与 UI 消费者会明确拒绝不能表示的 developer 历史。为已经接受的表示增加向后兼容的消费者支持,与新增格式是不同的变更。 + + +### Fork 生成的结果 + +Fork 种子构造归核心 Session 所有,不属于此迁移。原生 V4 接纳它生成的 `TOOL_NOT_STARTED` 合成错误结果,其 id 为 `forked-tool-result--`,角色为 tool,source/call id 匹配,带 `isError: true`、`ToolNotStartedError` 和一个 text block。追加结果携带自身序号且没有源引用;后续替换保留更早的后缀,并精确引用那个原始结果。分支专用文本保留,不归一化为崩溃恢复措辞。 + +已经开始的 fork 调用使用 `TOOL_OUTCOME_UNKNOWN` 错误结果,并保留记录的开始引用。它们遵循普通已开始调用的校验;上文专用于 not-started 的身份规则不适用于它们。Fork 构造通过 `turn/end.reason.kind: 'forked'` 关闭开放尾部,保留先前已结束的 step 和 turn。 + +普通 interrupted not-started 修复保留 canonical 历史整数后缀和精确的崩溃恢复文本。两种形式都必须按生命周期规则结算一个已声明调用。Stage 保留已有 fork/call/message id;它不从字符串前缀推断祖先关系,也不执行工具。 + + +### 校验入口与恢复 + +| 入口 | 检查与限制 | +|---|---| +| V4 codec 解码 | 已发布物理分帧加 V4 行接纳。Required 前代 PTC 标签、已退役 system header 和自身负责的错误原生字段,在 recoverable 后缀抑制前被拒绝。 | +| V4 codec 编码 | 同样的原生行检查;writer 仍校验 ignorable developer 载荷。 | +| 原生 catalog,`validation: 'transformed'` | 只有 codec 检查;因为没有执行迁移,跳过产物恢复。这不是完整原生校验。 | +| 历史 catalog,`validation: 'transformed'` | 转换后执行代际自有的 V4 恢复;跳过已安装 Session 的通用校验。 | +| Catalog,`validation: 'current'` | 代际自有 V4 检查加已安装当前 Session 的 header、信封、消息、表面与投影校验。Fixture 与发布验证使用 strict recovery。 | +| 原生 JSONL scanner | 在恢复前把已安装词汇表传给行接纳,并在暴露已接纳前缀前执行必需的 V4 关系检查。 | + +支持词汇表的恢复器拒绝未知 required 事件。未知 ignorable 载荷不被解释;required `tool/code-dispatch-start` / `tool/code-dispatch` 作为退役语法被拒绝,而 ignorable 前代事件保持不透明。没有词汇表时,物理解码器推迟解释 ignorable developer 载荷;知道 developer 事件的原生读取器必须在接纳 recoverable 后缀前校验它们。只有被接纳的 inherited marker 才能确定截点。 + +----- + + +## 理解实现 + +
+实现内部机制 — 点击展开 + +迁移声明创建相互独立的流式 Stage。紧凑事件段通过迭代器展开,不生成中间事件数组。V3 到 V4 Stage 在发出 V4 事件时一次性重写历史消息来源并提升历史工具结果包装。V4 编解码器只为物理头部和源范围分帧使用已发布 V2 编解码器,并直接校验原生工具角色行;它不会调用已发布 V3 校验器或源转换视图。JSONL 扫描器在抑制可恢复行之前调用 `assertV4RowAdmission`,并在返回完整逻辑前缀之前调用共用的强制关系校验器。 + +目标恢复器校验原生字段和强制跨事件关系,然后返回原始产物。未知的可忽略事件保持不透明,未完成的继承压缩事务在 end-seed 标记处结束。本包不发布运行时不变量伴随插件,因为这个纯函数库不拥有独立维护的运行时观测。 + +
+ +----- + + +## 进一步探索 + +- [格式版本与发布状态](../../../docs/session-format-status.zh.md) — 当前检出写入版本与已发布格式的权威记录。 +- [添加 Session 格式版本](../../../docs/cookbook/adding-a-session-format-version.zh.md) — 相邻迁移边的集成与校验。 +- [JSONL 持久化](../session-persistence-jsonl/README.zh.md) — 不可变代际选择与发布。 + +----- + + +## 模型体验 + +### 历史恢复 + +#### 模型看到什么 + +历史请求保留记录的消息与模型配置。[迁移 Stage](src/migration.ts)将 `tool/result` 载荷表示为工具角色消息,不添加模型可见内容;目录记录不会直接进入模型消息,后续子代理列举可以发现历史子 Session。 + +#### Token 影响 + +转换不改变请求文本或承载 token 的数据。 + +#### KV Cache 影响 + +该迁移边保留记录的请求前缀。提供方缓存的可用性和淘汰策略不属于本库职责。 + +## 已知限制与待办工作 + + + +- **历史转换器覆盖范围** — 未支持的源表示可能拒绝迁移,不发布后继文件,也不修改源文件。一方录制不等于第三方扩展全集。V4 发布后,只要输出仍兼容 V4,后续转换器修复就可以增加支持。解释流起始块的额外字段或处理未来投递代际,应以具体格式变更为依据。 +- **已接受 V4 转换**——[检查点](../../../docs/session-format-status.zh.md#finalization-record)保护已接受历史。向后兼容的新增可以通过新的确认记录保留 V4;破坏性变更要求后继版本。已写入的 V4 文件不会重跑此入边,历史输入保持不变。 +- **V5 前置读取器**——V4 子日志证据目前经过已安装目录。后续写入器在改变该目录前,须绑定固定代际的 V4 前置读取。导出的 V4 恢复器提供代际自有检查;完整的通用消息接纳还使用已安装的 Session 校验。 +- **历史嵌套工具结果**——当前迁移拒绝包含另一个 tool-result wrapper 的结果。原始代际保持完整,且不发布 V4 successor。后续转换器可以支持有证据的源数据场景,而不改变既定 V4 格式;[迁移 cookbook](../../../docs/cookbook/adding-a-session-format-version.zh.md#stages-and-validation) 定义了这一区别。 +- **历史扩展消费者**——带前缀的消息与结果字段保留 JSON 数据,不激活核心字段。消费者必须明确理解这些字段后才能解释它们。 +- **依赖保留的子日志**——仅凭父日志无法恢复未记录的子 id、创建时间或 descriptor。删除的子 Session 无法从工具参数恢复;已存在的父目录记录仍保留。 +- **历史目录项缺失**——没有恰好一个受支持的自身 descriptor 时,不补填父目录缺失项。子日志仍可按 id 读取;当前 V4 读取不会重新扫描子日志来补齐该条目。 +- **存储范围**——事实只覆盖同一持久化根目录内可识别的子 Session。跨根目录导入和损坏日志修复不属于此迁移。 + + +### 开发备注 + +
+维护者工作上下文 — 点击展开 + +无。 + +
diff --git a/packages/session/session-format-v3-to-v4/package.json b/packages/session/session-format-v3-to-v4/package.json new file mode 100644 index 0000000000..d99577e387 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/package.json @@ -0,0 +1,51 @@ +{ + "name": "@deepseek-ai/dsh-session-format-v3-to-v4", + "description": "Streaming tool-role migration and delivery validation from Session V3 to V4", + "version": "0.1.6-alpha.2", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", + "directory": "packages/session/session-format-v3-to-v4" + }, + "type": "module", + "main": "lib/index.js", + "types": "lib/types/index.d.ts", + "exports": { + ".": { + "types": "./lib/types/index.d.ts", + "default": "./lib/index.js" + }, + "./src/*": "./src/*", + "./package.json": "./package.json" + }, + "files": [ + "lib/index.js", + "lib/types/**/*.d.ts" + ], + "license": "MIT", + "dsh": { + "sessionFormatMigration": { + "from": 3, + "to": 4, + "export": ".", + "migration": "sessionFormatV3ToV4", + "sourceCodec": "releasedV3SessionFormatCodec", + "targetCodec": "releasedV4SessionFormatCodec", + "targetHeaderValidator": "assertReleasedV4Header", + "targetRestorer": "restoreReleasedV4Artifact" + } + }, + "dependencies": { + "@deepseek-ai/dsh-session-format": "workspace:^", + "@deepseek-ai/dsh-session-format-v2-to-v3": "workspace:^" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "workspace:^" + }, + "devDependencies": { + "@deepseek-ai/cordis": "workspace:^" + } +} diff --git a/packages/session/session-format-v3-to-v4/src/codec.ts b/packages/session/session-format-v3-to-v4/src/codec.ts new file mode 100644 index 0000000000..b7cf4e7a2b --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/codec.ts @@ -0,0 +1,75 @@ +/** V4 framing with native tool-role admission and released physical rows. */ + +import { SessionFormatError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatCodec, SessionFormatCurrentEncoder, SessionFormatHeader, SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { releasedV2SessionFormatCodec } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { assertV4SourceRowAdmission } from './message-sources.ts' +import { assertV4RetiredSyntax } from './retired-syntax.ts' +import { assertV4SystemMessageFields } from './system-message.ts' +import { assertV4DeveloperData } from './developer.ts' +import { assertV4ForkResult } from './fork-result.ts' +import { assertV4ToolResultMessage } from './tool-role.ts' +import { assertReleasedV4Header } from './validation.ts' + +function physicalV2(value: unknown): SessionFormatHeader { + if (!isSessionFormatJsonObject(value) || value['version'] !== 4) throw new SessionFormatError('expected format v4 physical header') + return { ...value, version: 2 } as SessionFormatHeader +} + +/** + * V4 physical encoder and decoder retain the released row framing while + * validating the native tool-role message directly. + */ +export const releasedV4SessionFormatCodec = Object.freeze({ + version: 4, + decodeHeader(value: unknown) { + return { ...releasedV2SessionFormatCodec.decodeHeader(physicalV2(value)), version: 4 } + }, + createDecoder(value, recovery) { + const decoder = releasedV2SessionFormatCodec.createDecoder(physicalV2(value), recovery) + return { + ...decoder, + header: { ...decoder.header, version: 4 }, + decodeRow(row, context) { + assertV4RowAdmission(row) + decoder.decodeRow(row, { + emitRun: context.emitRun.bind(context), + emitEvent: context.emitEvent.bind(context), + }) + }, + } + }, + encodeHeader(header, inheritedEventCount) { + assertReleasedV4Header(header) + return { ...releasedV2SessionFormatCodec.encodeHeader({ ...header, version: 2 }, inheritedEventCount), version: 4 } + }, + encodeEvent(event: SessionFormatEvent) { + if (event.type === 'developer/message' && event['ignorable'] === true) { + assertV4DeveloperData(event) + assertV4RetiredSyntax(event) + } + assertV4RowAdmission(event) + return releasedV2SessionFormatCodec.encodeEvent(event) + }, +} satisfies SessionFormatCodec & SessionFormatCurrentEncoder) + +/** + * Apply native V4 admission before a scanner discards a recoverable suffix. + * Ignorable developer payloads require reader vocabulary; physical decoding defers them. + * @param row - parsed physical row before framing and source-event range decoding. + * @param knownEventTypes - installed event types, supplied by native readers before tail recovery. + */ +export function assertV4RowAdmission(row: unknown, knownEventTypes?: ReadonlySet): void { + if (isSessionFormatJsonObject(row)) { + if (row['type'] === 'developer/message' && row['ignorable'] === true + && knownEventTypes?.has('developer/message') !== true) return + assertV4DeveloperData(row as unknown as SessionFormatEvent) + } + assertV4SourceRowAdmission(row) + assertV4RetiredSyntax(row) + assertV4SystemMessageFields(row) + if (!isSessionFormatJsonObject(row) || row['type'] !== 'tool/result') return + const event = row as unknown as SessionFormatEvent + assertV4ToolResultMessage(event) + assertV4ForkResult(event) +} diff --git a/packages/session/session-format-v3-to-v4/src/content.ts b/packages/session/session-format-v3-to-v4/src/content.ts new file mode 100644 index 0000000000..51cc21e12b --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/content.ts @@ -0,0 +1,95 @@ +/** V3 content tags and request-tool fields admitted before V4 interpretation. */ + +import { SessionFormatError, SessionFormatUnsupportedMigrationError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { mapEventMessages } from './sources.ts' + +const V3_BLOCK_TYPES = new Set(['text', 'reasoning', 'image', 'file', 'tool-call', 'tool-result']) + +function migrateBlock(value: SessionFormatJsonValue, subject: string): SessionFormatJsonValue { + if (!isSessionFormatJsonObject(value) || typeof value['type'] !== 'string') { + throw new SessionFormatError(`${subject} requires content blocks with string type tags`) + } + const type = value['type'] + if (V3_BLOCK_TYPES.has(type)) return value + return { ...value, type: `plugin:${type}` } +} + +/** + * Convert declared content tags while keeping arguments and extension data opaque. + * @param value - released content array. + * @param subject - owning event and content location for diagnostics. + * @returns content in the same order, sharing unchanged blocks and image references. + */ +export function migrateV3Content(value: SessionFormatJsonValue | undefined, subject: string): SessionFormatJsonValue[] { + if (!Array.isArray(value)) throw new SessionFormatError(`${subject} content must be an array`) + const blocks = value as readonly SessionFormatJsonValue[] + const mapped = blocks.map((block, index) => migrateBlock(block, `${subject}[${index}]`)) + return mapped.every((block, index) => block === value[index]) ? value as SessionFormatJsonValue[] : mapped +} + +function migrateMessage(message: SessionFormatJsonObject, subject: string): SessionFormatJsonObject { + const content = migrateV3Content(message['content'], subject) + return content === message['content'] ? message : { ...message, content } +} + +function migrateChunk(value: SessionFormatJsonValue | undefined, subject: string): SessionFormatJsonValue | undefined { + if (!isSessionFormatJsonObject(value)) return value + if (value['type'] === 'block-end') { + const block = migrateBlock(value['block'] as SessionFormatJsonValue, `${subject}.block`) + return block === value['block'] ? value : { ...value, block } + } + if (value['type'] !== 'block-start') return value + const original = value['blockType'] + if (typeof original !== 'string') throw new SessionFormatError(`${subject} blockType must be a string`) + const blockType = V3_BLOCK_TYPES.has(original) ? original : `plugin:${original}` + return blockType === original ? value : { ...value, blockType } +} + +/** + * Convert declared V3 extension content and stream tags after canonical result lifting. + * @param event - source event after producer attribution conversion. + * @returns the event with namespaced content tags, retaining all coordinates and other fields. + * @throws {SessionFormatUnsupportedMigrationError} A V3 tool definition contains the V4-only deferLoading field. + */ +export function migrateV3EventContent(event: SessionFormatEvent): SessionFormatEvent { + const subject = `format v3 ${event.type} at seq ${event.seq}` + let mapped = mapEventMessages(event, message => migrateMessage(message, subject)) + if (!isSessionFormatJsonObject(mapped.data)) return mapped + let data = mapped.data + const contentField = (key: string): void => { + const content = migrateV3Content(data[key], `${subject}.${key}`) + if (content !== data[key]) data = { ...data, [key]: content } + } + if (event.type === 'compaction/summary') { + contentField('summary') + if (data['rawOutput'] !== undefined) contentField('rawOutput') + } else if (event.type === 'tool/ptc-dispatch') contentField('content') + else if (event.type === 'team/message/queued' && isSessionFormatJsonObject(data['message'])) { + const message = migrateMessage(data['message'], subject) + if (message !== data['message']) data = { ...data, message } + } + if (event.type === 'request/header' && isSessionFormatJsonObject(data['header'])) { + const tools = data['header']['tools'] + if (Array.isArray(tools)) { + for (const [index, tool] of (tools as readonly SessionFormatJsonValue[]).entries()) { + if (isSessionFormatJsonObject(tool) && Object.hasOwn(tool, 'deferLoading')) { + throw new SessionFormatUnsupportedMigrationError( + `${subject}.header.tools[${index}] contains deferLoading, which is only defined in V4`, + ) + } + } + } + } + if ((event.type === 'assistant/message' || event.type === 'assistant/attempt') && Array.isArray(data['stream'])) { + const stream = data['stream'] as readonly SessionFormatJsonValue[] + const converted = stream.map((entry, index) => { + if (!isSessionFormatJsonObject(entry) || entry['type'] !== 'chunk') return entry + const chunk = migrateChunk(entry['chunk'], `${subject}.stream[${index}]`) + return chunk === entry['chunk'] ? entry : { ...entry, chunk: chunk as SessionFormatJsonValue } + }) + if (converted.some((entry, index) => entry !== stream[index])) data = { ...data, stream: converted } + } + if (data !== mapped.data) mapped = { ...mapped, data } + return mapped +} diff --git a/packages/session/session-format-v3-to-v4/src/developer.ts b/packages/session/session-format-v3-to-v4/src/developer.ts new file mode 100644 index 0000000000..9200831177 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/developer.ts @@ -0,0 +1,113 @@ +/** Native V4 developer-message and deferred-tool-schema validation. */ + +import { SessionFormatError, isSessionFormatJsonObject, sessionFormatCount } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' + +function assertToolChange(block: unknown, developer: boolean): void { + if (!isSessionFormatJsonObject(block) || (block['type'] !== 'tool-addition' && block['type'] !== 'tool-removal')) return + if (!developer) throw new SessionFormatError(`format v4 ${block['type']} requires developer role`) + if (typeof block['toolName'] !== 'string' || block['toolName'].length === 0) { + throw new SessionFormatError(`format v4 ${block['type']} requires a nonempty toolName`) + } + if (block['type'] === 'tool-addition' && Object.hasOwn(block, 'tool')) { + throw new SessionFormatError('format v4 tool-addition must omit inline tool definitions') + } +} + +function assertContent(value: SessionFormatJsonValue | undefined, developer = false): void { + if (Array.isArray(value)) value.forEach((block) => { assertToolChange(block, developer) }) +} + +function assertDeveloperMessage(message: SessionFormatJsonObject): void { + assertContent(message['content'], true) + const source = message['source'] + if (typeof message['id'] !== 'string' || message['id'].length === 0 + || !Array.isArray(message['content']) || !isSessionFormatJsonObject(source) + || typeof source['kind'] !== 'string' || source['kind'].length === 0 || source['kind'] === 'plugin') { + throw new SessionFormatError('format v4 developer message requires id, role, content, and a producer-owned source') + } +} + +/** Ordinary-message corruption belongs to the decoder; recognized V4-only values are refused here. */ +function assertOrdinaryMessage(value: SessionFormatJsonValue | undefined): void { + if (!isSessionFormatJsonObject(value)) return + if (value['role'] === 'developer') { + throw new SessionFormatError('format v4 developer/message and developer role must occur together') + } + assertContent(value['content']) +} + +/** + * Validate native V4 developer messages, tool-change blocks, and deferred tool schemas. + * Additional developer JSON fields are preserved. Malformed legacy message + * slots remain available to recoverable decoding. + * @param event - logical event or physical row before source-event range decoding. + */ +export function assertV4DeveloperData(event: SessionFormatEvent): void { + const data = event.data + if (!isSessionFormatJsonObject(data)) { + if (event.type === 'developer/message') throw new SessionFormatError('format v4 developer/message data must be an object') + return + } + if (event.type === 'developer/message') { + const message = data['message'] + if (!isSessionFormatJsonObject(message) || message['role'] !== 'developer') { + throw new SessionFormatError('format v4 developer/message requires turn, step, and a developer message') + } + for (const field of ['turn', 'step']) { + if (sessionFormatCount(data[field], `developer/message ${field}`) === 0) { + throw new SessionFormatError(`developer/message ${field} must be positive`) + } + } + assertDeveloperMessage(message) + const content = message['content'] as SessionFormatJsonValue[] + const hasAdditions = content.some(block => isSessionFormatJsonObject(block) && block['type'] === 'tool-addition') + if (hasAdditions) { + sessionFormatCount(data['headerSeq'], 'developer/message headerSeq') + } else if (Object.hasOwn(data, 'headerSeq')) { + throw new SessionFormatError('format v4 developer/message must omit headerSeq without tool additions') + } + } else { + switch (event.type) { + case 'user/message': + assertOrdinaryMessage(data) + break + case 'system/message': + case 'assistant/message': + case 'tool/result': + assertOrdinaryMessage(data['message']) + break + case 'agent/inbox/spliced': + case 'session/title-llm-request': { + const messages = data[event.type === 'agent/inbox/spliced' ? 'inserted' : 'messages'] + if (Array.isArray(messages)) messages.forEach(assertOrdinaryMessage) + break + } + } + } + if (event.type === 'compaction/summary') { + assertContent(data['summary']) + assertContent(data['rawOutput']) + } + if ((event.type === 'assistant/message' || event.type === 'assistant/attempt') && Array.isArray(data['stream'])) { + for (const entry of data['stream']) { + if (!isSessionFormatJsonObject(entry) || entry['type'] !== 'chunk') continue + const chunk = entry['chunk'] + if (!isSessionFormatJsonObject(chunk)) continue + if (chunk['type'] === 'block-end') assertToolChange(chunk['block'], false) + if (chunk['type'] === 'block-start' && (chunk['blockType'] === 'tool-addition' || chunk['blockType'] === 'tool-removal')) { + throw new SessionFormatError('format v4 tool-change blocks require developer role') + } + } + } + if (event.type === 'request/header' && isSessionFormatJsonObject(data['header'])) { + const header = data['header'] + const tools = header['tools'] + if (Array.isArray(tools)) { + for (const tool of tools) { + if (!isSessionFormatJsonObject(tool) || !Object.hasOwn(tool, 'deferLoading')) continue + if (tool['deferLoading'] !== true) throw new SessionFormatError('format v4 tool deferLoading must be true when present') + } + } + } +} diff --git a/packages/session/session-format-v3-to-v4/src/extension-identities.ts b/packages/session/session-format-v3-to-v4/src/extension-identities.ts new file mode 100644 index 0000000000..20b9c732ed --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/extension-identities.ts @@ -0,0 +1,79 @@ +/** Fixed V3 event vocabulary and namespaced historical opaque events. */ + +import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' + +// This historical list must not inherit additions or removals from the current Session event list. +/* jscpd:ignore-start */ +/** First-party event names understood by the released V3 reader, independent of the installed writer. */ +export const RELEASED_V3_EVENT_TYPES: ReadonlySet = new Set([ + 'agent-preset/selected', + 'agent/inbox/spliced', + 'approval/asked', + 'approval/decided', + 'approval/policy', + 'assistant/attempt', + 'assistant/message', + 'command/done', + 'command/run', + 'compaction/end', + 'compaction/prune', + 'compaction/start', + 'compaction/summary', + 'deliverables/presented', + 'feedback/message-delete', + 'feedback/message-put', + 'feedback/record', + 'goal/change', + 'hook/invoked', + 'hook/result', + 'image/offload', + 'llm/retry', + 'llm/retry-started', + 'model/selection', + 'permission/preset', + 'plan/mode', + 'request/context', + 'request/header', + 'sandbox/mode', + 'schedule/change', + 'session-log-deepseek/delivery-accepted', + 'session/end-seed', + 'session/title', + 'session/title-llm-request', + 'step/end', + 'step/start', + 'subagent/catalog', + 'subagent/descriptor', + 'subagent/model-selection-policy', + 'system/message', + 'team/member', + 'team/message/delivered', + 'team/message/queued', + 'team/task', + 'todo/write', + 'tool-workflow/agent-end', + 'tool-workflow/agent-start', + 'tool-workflow/run-end', + 'tool-workflow/run-start', + 'tool/call', + 'tool/ptc-dispatch', + 'tool/ptc-dispatch-start', + 'tool/result', + 'turn/end', + 'turn/start', + 'user/message', + 'web/deepseek-search-llm-request', + 'workspace/changes', +]) +/* jscpd:ignore-end */ + +/** + * Keep unknown ignorable events opaque after header promotion. + * @param event - original V3 event; this incoming identity conversion is applied once. + * @returns the same event or an ignorable namespaced event retaining its payload and coordinates. + */ +export function namespaceV3OpaqueEvent(event: SessionFormatEvent): SessionFormatEvent { + return event['ignorable'] === true && !RELEASED_V3_EVENT_TYPES.has(event.type) + ? { ...event, type: `plugin:${event.type}`, ignorable: true } + : event +} diff --git a/packages/session/session-format-v3-to-v4/src/facts.ts b/packages/session/session-format-v3-to-v4/src/facts.ts new file mode 100644 index 0000000000..a08f2bda20 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/facts.ts @@ -0,0 +1,85 @@ +/** Historical child identity reduced to the fields required by a parent's catalog. */ + +import { SessionFormatError, SessionFormatUnsupportedMigrationError, isSessionFormatJsonObject, sessionFormatCount } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatArtifact, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' + +/** + * Collect a child's own descriptor without requiring one before its parent catalog is read. + * @param artifact - validated historical child artifact with its exact inherited cut. + * @returns compact child identity and descriptor evidence for catalog completion. + */ +export function historicalChildCatalogSource(artifact: SessionFormatArtifact): SessionFormatJsonObject { + const header = artifact.header + if (header.origin !== 'subagent' || header.parentSession === undefined) { + throw new SessionFormatUnsupportedMigrationError('catalog migration requires a subagent child with a direct parent') + } + const descriptors = artifact.events.filter(event => event.type === 'subagent/descriptor' && event.seq >= artifact.inheritedEventCount) + return { + childId: header.id, childCreatedAt: header.createdAt, + descriptorCount: descriptors.length, descriptor: descriptors[0]?.data ?? null, + } +} + +/** + * Validate supplemental child evidence supplied across the migration JSON interface. + * @param value - collected child identity and optional descriptor. + * @returns validated evidence; descriptor interpretation is deferred until parent membership is known. + */ +export function childCatalogSource(value: SessionFormatJsonValue): SessionFormatJsonObject { + if (!isSessionFormatJsonObject(value) || typeof value['childId'] !== 'string' + || !Object.hasOwn(value, 'descriptor')) { + throw new SessionFormatUnsupportedMigrationError('catalog migration requires historical child identity and descriptor evidence') + } + sessionFormatCount(value['childCreatedAt'], 'catalog child creation time') + sessionFormatCount(value['descriptorCount'], 'child descriptor count') + return value +} + +/** + * Interpret only the discovery fields of known historical descriptors. + * @param source - validated child evidence. + * @returns a catalog fact, or undefined without exactly one supported own descriptor. + */ +export function childCatalogFact(source: SessionFormatJsonObject): SessionFormatJsonObject | undefined { + const id = source['childId'] as string + const descriptor = source['descriptor'] + const count = source['descriptorCount'] as number + const known = isSessionFormatJsonObject(descriptor) && [1, 2, 3].includes(descriptor['version'] as number) + if (count !== 1 || !known) return undefined + if (typeof descriptor['provider'] !== 'string') { + throw new SessionFormatUnsupportedMigrationError(`${childCatalogSubject(source)} has an invalid subagent descriptor provider`) + } + return catalogFact({ + version: 0, childId: id, childCreatedAt: source['childCreatedAt'] as number, + // V1 described only continuable children and carried no mode field. + mode: descriptor['version'] === 1 ? 'continuable' : descriptor['mode'] as SessionFormatJsonValue, + ...(descriptor['label'] === undefined ? {} : { label: descriptor['label'] }), + }, childCatalogSubject(source)) +} + +/** + * Validate the historical fields used for catalog membership without interpreting extensions. + * @param value - catalog payload or prepared historical discovery fact. + * @param subject - event type or child identity used in rejection diagnostics. + * @returns validated catalog payload. + */ +export function catalogFact(value: SessionFormatJsonValue, subject = 'subagent/catalog'): SessionFormatJsonObject { + if (!isSessionFormatJsonObject(value) || value['version'] !== 0 + || typeof value['childId'] !== 'string' + || (value['mode'] !== 'continuable' && value['mode'] !== 'one-shot') + || (value['mode'] === 'continuable' && typeof value['label'] !== 'string') + || (value['label'] !== undefined && typeof value['label'] !== 'string')) { + throw new SessionFormatError(`${subject} requires a complete version 0 catalog fact`) + } + sessionFormatCount(value['childCreatedAt'], 'catalog child creation time') + return value +} + +/** + * Name the child and its optional storage-owned location in a migration diagnostic. + * @param source - validated supplemental child evidence. + * @returns a child identity with its source path when persistence supplied one. + */ +export function childCatalogSubject(source: SessionFormatJsonObject): string { + return `Session ${source['childId'] as string}${typeof source['sourcePath'] === 'string' ? ` (raw log: ${source['sourcePath']})` : ''}` +} diff --git a/packages/session/session-format-v3-to-v4/src/fork-result.ts b/packages/session/session-format-v3-to-v4/src/fork-result.ts new file mode 100644 index 0000000000..352a31d1a7 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/fork-result.ts @@ -0,0 +1,40 @@ +/** Native V4 fork-result identity and not-started error validation. */ + +import { SessionFormatError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' + +/** + * Validate fork-generated not-started results without changing their identity or text. + * Append results carry their own sequence; replacement results retain an earlier identity. + * @param row - logical event or physical event row. + */ +export function assertV4ForkResult(row: unknown): void { + if (!isSessionFormatJsonObject(row) || row['type'] !== 'tool/result') return + const data = row['data'] + if (!isSessionFormatJsonObject(data)) return + const error = data['error'] + const message = data['message'] + if (!isSessionFormatJsonObject(error) || error['code'] !== 'TOOL_NOT_STARTED' + || !isSessionFormatJsonObject(message) || typeof message['id'] !== 'string' + || !message['id'].startsWith('forked-tool-result-')) return + const source = message['source'] + const callId = isSessionFormatJsonObject(source) ? source['callId'] : undefined + const prefix = `forked-tool-result-${String(callId)}-` + const suffix = message['id'].slice(prefix.length) + const operation = row['surfaceOp'] + const replacement = isSessionFormatJsonObject(operation) && operation['op'] === 'replace' + const sequence = Number(suffix) + const content = message['content'] + const text: unknown = Array.isArray(content) && content.length === 1 ? content[0] : undefined + const sourceEventSeqs = row['sourceEventSeqs'] + if (typeof callId !== 'string' || !message['id'].startsWith(prefix) + || !/^(0|[1-9]\d*)$/.test(suffix) || !Number.isSafeInteger(sequence) + || (replacement ? typeof row['seq'] !== 'number' || sequence >= row['seq'] : sequence !== row['seq']) + || error['name'] !== 'ToolNotStartedError' + || (!replacement && (sourceEventSeqs !== undefined || operation !== 'append')) + || (replacement && (!Array.isArray(sourceEventSeqs) || sourceEventSeqs.length !== 1 || sourceEventSeqs[0] !== sequence)) + || message['role'] !== 'tool' || message['isError'] !== true || message['toolCallId'] !== callId + || !isSessionFormatJsonObject(source) || source['kind'] !== 'tool' + || !isSessionFormatJsonObject(text) || text['type'] !== 'text' || typeof text['text'] !== 'string') { + throw new SessionFormatError('invalid V4 not-started fork result') + } +} diff --git a/packages/session/session-format-v3-to-v4/src/index.ts b/packages/session/session-format-v3-to-v4/src/index.ts new file mode 100644 index 0000000000..25254a3294 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/index.ts @@ -0,0 +1,8 @@ +/** Tool-role V3-to-V4 migration with native V4 framing and delivery validation. */ + +export { releasedV3SessionFormatCodec } from '@deepseek-ai/dsh-session-format-v2-to-v3' +export * from './codec.ts' +export * from './migration.ts' +export { assertReleasedV4Header, assertReleasedV4Relationships, restoreReleasedV4Artifact } from './validation.ts' +export { historicalChildCatalogSource } from './facts.ts' +export { RELEASED_V3_EVENT_TYPES } from './extension-identities.ts' diff --git a/packages/session/session-format-v3-to-v4/src/message-sources.ts b/packages/session/session-format-v3-to-v4/src/message-sources.ts new file mode 100644 index 0000000000..9cf580b265 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/message-sources.ts @@ -0,0 +1,42 @@ +/** Native source admission preserves unknown attribution and refuses retired plugin wrappers. */ + +import { SessionFormatError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { mapEventMessages } from './sources.ts' + +function source(message: Readonly>): void { + const value = message['source'] + if (!isSessionFormatJsonObject(value) || typeof value['kind'] !== 'string' || value['kind'].length === 0 || value['kind'] === 'plugin') { + throw new SessionFormatError('format v4 message requires a producer-owned source kind') + } +} + +/** + * Validate producer attribution in every declared durable message slot. + * @param event - complete native V4 event before Session adoption. + */ +export function assertV4MessageSources(event: SessionFormatEvent): void { + mapEventMessages(event, (message) => { + source(message) + return message + }) +} + +/** + * Refuse retired source syntax even after a malformed recoverable row; leave incomplete messages to decoding. + * @param row - parsed row whose incomplete values have not been classified by the scanner. + */ +export function assertV4SourceRowAdmission(row: unknown): void { + if (!isSessionFormatJsonObject(row) || !isSessionFormatJsonObject(row['data'])) return + const data = row['data'] + const messages = row['type'] === 'user/message' ? [data] + : row['type'] === 'system/message' || row['type'] === 'assistant/message' || row['type'] === 'tool/result' ? [data['message']] + : row['type'] === 'agent/inbox/spliced' ? data['inserted'] + : row['type'] === 'session/title-llm-request' ? data['messages'] : [] + if (!Array.isArray(messages)) return + for (const message of messages) { + if (!isSessionFormatJsonObject(message)) continue + const value = message['source'] + if (isSessionFormatJsonObject(value) && value['kind'] === 'plugin') source(message) + } +} diff --git a/packages/session/session-format-v3-to-v4/src/migration.ts b/packages/session/session-format-v3-to-v4/src/migration.ts new file mode 100644 index 0000000000..3b1c1de60a --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/migration.ts @@ -0,0 +1,131 @@ +/** Append historical child facts after converting V3 source events to V4. */ + +import { defineSessionFormatMigration, SessionFormatError, SessionFormatUnsupportedMigrationError, isSessionFormatJsonObject, sessionFormatCount } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatEventRun, SessionFormatJsonObject, SessionFormatJsonValue, SessionFormatMigration, SessionFormatMigrationContext, SessionFormatMigrationStage, SessionFormatMigrationStageInput } from '@deepseek-ai/dsh-session-format' +import { assertReleasedV3Header } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { mapEventMessages, rewriteV3MessageSource } from './sources.ts' +import { liftToolResult } from './tool-role.ts' +import { migrateV3EventContent } from './content.ts' +import { namespaceV3OpaqueEvent, RELEASED_V3_EVENT_TYPES } from './extension-identities.ts' +import { assertReleasedV4Header, validateDeliveryAccepted } from './validation.ts' +import { catalogFact, childCatalogSource, childCatalogFact, childCatalogSubject } from './facts.ts' + +/** Header-only migration declaration; body restoration requires explicit child evidence. */ +export const sessionFormatV3ToV4 = defineSessionFormatMigration({ + name: '@deepseek-ai/dsh-session-format-v3-to-v4', + fromVersion: 3, + toVersion: 4, + migrateHeader(header) { + assertReleasedV3Header(header) + return { ...header, version: 4 } + }, + createStage() { + throw new SessionFormatUnsupportedMigrationError('V3 catalog migration requires explicit historical child facts, including an empty array for a parent without children') + }, + validateTargetHeader: assertReleasedV4Header, +}) + +/** + * Bind one parent's historical child evidence to its V3→V4 migration. + * @param children - complete child evidence retained unchanged for the lifetime of this declaration; an empty array declares no children. + * @returns an adjacent migration that creates independent stages with the supplied evidence. + */ +export function createSessionFormatV3ToV4(children: readonly SessionFormatJsonValue[]): SessionFormatMigration { + return defineSessionFormatMigration({ + ...sessionFormatV3ToV4, + createStage: input => new ReleasedV3ToV4Stage(input, children), + }) +} + +class ReleasedV3ToV4Stage implements SessionFormatMigrationStage { + readonly headerInheritedEventCount?: number + private readonly candidates: readonly SessionFormatJsonObject[] + private readonly catalogs: SessionFormatJsonValue[] = [] + private cut: number | undefined + private nextSeq = 0 + private time: number + private foreignDeliverySeq: number | undefined + + constructor(private readonly input: SessionFormatMigrationStageInput, children: readonly SessionFormatJsonValue[]) { + this.candidates = children.map(childCatalogSource).sort((left, right) => + (left['childCreatedAt'] as number) - (right['childCreatedAt'] as number) + || (left['childId'] === right['childId'] ? 0 : (left['childId'] as string) < (right['childId'] as string) ? -1 : 1)) + this.cut = input.sourceHeader.isSeeded ? undefined : 0 + if (!input.sourceHeader.isSeeded) this.headerInheritedEventCount = 0 + this.time = input.sourceHeader.createdAt + } + + transformEvent(event: SessionFormatEvent, context: SessionFormatMigrationContext): void { + if (event.seq !== this.nextSeq++) throw new SessionFormatError('V3 source events must be dense') + this.time = event.time + if (event.type === 'session/end-seed' && isSessionFormatJsonObject(event.data) && event.data['inherited'] === true) { + if (!this.input.sourceHeader.isSeeded) throw new SessionFormatError('unseeded format v3 Session contains an inherited end-seed marker') + this.cut = event.seq + this.catalogs.length = 0 + } else if (event.type === 'subagent/catalog') { + this.catalogs.push(event.data) + } + const deliveryId = validateDeliveryAccepted(event, 3) + if (event.type === 'session-log-deepseek/delivery-accepted') { + if ((event.data as SessionFormatJsonObject)['sessionFormatVersion'] === 4) { + throw new SessionFormatUnsupportedMigrationError('format v3 delivery marker claims target format v4') + } + if (deliveryId !== undefined && deliveryId !== this.input.sourceHeader.id) this.foreignDeliverySeq = event.seq + } + const opaque = namespaceV3OpaqueEvent(event) + if (opaque !== event) { context.emitEvent(opaque); return } + if (!RELEASED_V3_EVENT_TYPES.has(event.type)) { + throw new SessionFormatUnsupportedMigrationError( + `format v3 contains unknown event type ${JSON.stringify(event.type)} at seq ${event.seq}`, + ) + } + const rewritten = mapEventMessages(event, (message) => { + const source = message['source'] + if (!isSessionFormatJsonObject(source)) return message + const converted = rewriteV3MessageSource(source, event.seq, message['role']) + return converted === source ? message : { ...message, source: converted } + }) + context.emitEvent(migrateV3EventContent(liftToolResult(rewritten))) + } + + transformRun(run: SessionFormatEventRun, context: SessionFormatMigrationContext): void { + for (const event of run.expand()) this.transformEvent(event, context) + } + + finish(context: SessionFormatMigrationContext): number { + const cut = sessionFormatCount(this.cut, 'V3 inherited event count') + // Catalog payloads belong to this Session only after the final inherited cut. + const existingCatalogs = new Map() + for (const data of this.catalogs) { + const fact = catalogFact(data) + const id = fact['childId'] as string + if (existingCatalogs.has(id)) throw new SessionFormatUnsupportedMigrationError(`duplicate catalog child ${id}`) + existingCatalogs.set(id, fact) + } + if (this.input.sourceInheritedEventCount !== undefined && cut !== this.input.sourceInheritedEventCount) { + throw new SessionFormatError('format v3 inherited cut disagrees with its source marker') + } + if (this.foreignDeliverySeq !== undefined + && (this.input.sourceHeader.parentSession === undefined || this.foreignDeliverySeq >= cut)) { + throw new SessionFormatError('current-generation delivery marker names the wrong Session') + } + for (const source of this.candidates) { + const id = source['childId'] as string + const existing = existingCatalogs.get(id) + const fact = childCatalogFact(source) + if (existing !== undefined) { + if (existing['childCreatedAt'] !== source['childCreatedAt']) { + throw new SessionFormatUnsupportedMigrationError(`${childCatalogSubject(source)} conflicts with its parent catalog`) + } + if (fact !== undefined && ['mode', 'label'].some(key => existing[key] !== fact[key])) { + throw new SessionFormatUnsupportedMigrationError(`${childCatalogSubject(source)} conflicts with its parent catalog`) + } + continue + } + if (fact === undefined) continue + existingCatalogs.set(id, fact) + context.emitEvent({ type: 'subagent/catalog', seq: this.nextSeq++, time: this.time, data: fact }) + } + return cut + } +} diff --git a/packages/session/session-format-v3-to-v4/src/relationships.ts b/packages/session/session-format-v3-to-v4/src/relationships.ts new file mode 100644 index 0000000000..aa50b3f3bf --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/relationships.ts @@ -0,0 +1,385 @@ +/** Mandatory native V4 relationships; incomplete tails retain their open transactions. */ + +import { isDeepStrictEqual } from 'node:util' +import { SessionFormatError, isSessionFormatJsonObject, sessionFormatCount } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatArtifact, SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' + +const SURFACE_TYPES = new Set(['system/message', 'user/message', 'developer/message', 'assistant/message', 'tool/result']) +const STEP_EVENT_TYPES = new Set(['system/message', 'developer/message', 'assistant/attempt']) +const RELATIONSHIP_TYPES = new Set([ + ...SURFACE_TYPES, ...STEP_EVENT_TYPES, 'turn/start', 'turn/end', 'step/start', 'step/end', + 'tool/call', 'request/header', 'request/context', 'tool/ptc-dispatch-start', 'tool/ptc-dispatch', + 'llm/retry', 'llm/retry-started', 'session/title', 'session/title-llm-request', 'command/run', + 'command/done', 'compaction/start', 'compaction/summary', 'compaction/end', 'compaction/prune', 'session/end-seed', +]) + +function record(value: SessionFormatJsonValue | undefined, subject: string): SessionFormatJsonObject { + if (!isSessionFormatJsonObject(value)) throw new SessionFormatError(`${subject} requires an object`) + return value +} + +function text(value: SessionFormatJsonValue | undefined, subject: string): string { + if (typeof value !== 'string' || value.length === 0) throw new SessionFormatError(`${subject} requires a nonempty string`) + return value +} + +function array(value: SessionFormatJsonValue | undefined, subject: string): readonly SessionFormatJsonValue[] { + if (!Array.isArray(value)) throw new SessionFormatError(`${subject} requires an array`) + return value as readonly SessionFormatJsonValue[] +} + +function earlier(value: SessionFormatJsonValue | undefined, seq: number, subject: string): number { + const coordinate = sessionFormatCount(value, subject) + if (coordinate >= seq) throw new SessionFormatError(`${subject} must name an earlier event`) + return coordinate +} + +interface ToolState { + readonly name: SessionFormatJsonValue | undefined + readonly arguments: SessionFormatJsonValue | undefined + started: boolean +} + +interface Compaction { + readonly id: string + readonly command: SessionFormatJsonValue | undefined + readonly turn: number | null + readonly seq: number + summarized: boolean +} + +/** One native artifact's lifecycle state; no state survives between reads. */ +class Relationships { + turn: number | null = null + step: number | null = null + nextTurn = 1 + nextStep = 1 + provider: SessionFormatJsonValue | undefined + surface: number[] = [] + protectedHead: number | undefined + compaction: Compaction | undefined + readonly tools = new Map() + readonly dispatches = new Map() + readonly retries: SessionFormatJsonObject[] = [] + readonly startedRetries = new Set() + readonly commands = new Set() + readonly orphanCompactions = new Set() + + constructor(readonly artifact: SessionFormatArtifact, readonly knownEventTypes: ReadonlySet) { + let start: number | undefined + for (const event of artifact.events) { + if (!knownEventTypes.has(event.type)) continue + if (event.type === 'compaction/start') start = event.seq + if (event.type === 'compaction/end') start = undefined + if (event.type === 'session/end-seed') { + if (start !== undefined) this.orphanCompactions.add(start) + start = undefined + } + } + } + + requireTurn(type: string): void { + if (this.turn === null) throw new SessionFormatError(`${type} is outside an open turn`) + } + + requireStep(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + if (this.turn === null || this.step === null || data['turn'] !== this.turn || data['step'] !== this.step) { + throw new SessionFormatError(`${event.type} does not match an open turn and step`) + } + } + + closeTools(type: string): void { + if (this.tools.size !== 0) throw new SessionFormatError(`${type} leaves unresolved tool call ${String(this.tools.keys().next().value)}`) + this.tools.clear() + } + + developer(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + if (data['headerSeq'] === undefined) return + const headerSeq = earlier(data['headerSeq'], event.seq, 'developer/message headerSeq') + const headerEvent = this.artifact.events[headerSeq] + if (headerEvent?.type !== 'request/header') { + throw new SessionFormatError('developer/message headerSeq must reference an earlier request/header') + } + if (!this.knownEventTypes.has(headerEvent.type)) { + throw new SessionFormatError('developer/message headerSeq must reference a known request/header') + } + const tools = record(record(headerEvent.data, 'request/header data')['header'], 'request header')['tools'] + const content = array(record(data['message'], 'developer message')['content'], 'developer content') + for (const value of content) { + if (!isSessionFormatJsonObject(value) || value['type'] !== 'tool-addition') continue + const toolName = value['toolName'] as string + const definitions = Array.isArray(tools) + ? tools.filter(tool => isSessionFormatJsonObject(tool) && tool['name'] === toolName) + : [] + if (definitions.length !== 1) { + throw new SessionFormatError(`developer/message tool-addition "${toolName}" must name exactly one tool in headerSeq ${headerSeq}`) + } + const definition = definitions[0] as SessionFormatJsonObject + if (typeof definition['description'] !== 'string' || !isSessionFormatJsonObject(definition['parameters'])) { + throw new SessionFormatError(`developer/message tool-addition "${toolName}" requires a complete tool definition in headerSeq ${headerSeq}`) + } + } + } + + foldSurface(event: SessionFormatEvent): void { + if (!SURFACE_TYPES.has(event.type)) return + if (event.type === 'system/message' && this.surface.length > 0 && this.protectedHead === undefined) { + throw new SessionFormatError('system/message requires a protected first surface head') + } + if (event['surfaceOp'] === 'append') { + if (event.type === 'system/message' && this.surface.length === 0) this.protectedHead = event.seq + this.surface.push(event.seq) + return + } + const operation = record(event['surfaceOp'], `${event.type} surfaceOp`) + const first = this.surface.indexOf(earlier(operation['startSeq'], event.seq, 'replacement start')) + const last = this.surface.indexOf(earlier(operation['endSeq'], event.seq, 'replacement end')) + if (first < 0 || last < first) throw new SessionFormatError(`${event.type} replacement range is not on the current surface`) + const removed = this.surface.slice(first, last + 1) + const sources = array(event['sourceEventSeqs'], 'replacement sourceEventSeqs') + if (removed.some(seq => !sources.includes(seq))) throw new SessionFormatError('replacement sourceEventSeqs omit a shadowed surface node') + if (this.protectedHead !== undefined && removed.includes(this.protectedHead)) { + if (event.type !== 'system/message' || removed.length !== 1) throw new SessionFormatError('surface replacement cannot shadow the protected system head') + this.protectedHead = event.seq + } + this.surface.splice(first, removed.length, event.seq) + } + + tool(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + if (event.type === 'tool/result' && event['surfaceOp'] !== 'append') { + this.requireTurn(event.type) + return + } + this.requireStep(event, data) + if (event.type === 'assistant/message') { + const message = record(data['message'], 'assistant message') + for (const value of array(message['content'], 'assistant content')) { + const block = record(value, 'assistant content block') + if (block['type'] !== 'tool-call') continue + const id = text(block['id'], 'tool call id') + if (this.tools.has(id)) throw new SessionFormatError(`assistant/message repeats advertised tool call ${id}`) + this.tools.set(id, { name: block['name'], arguments: block['arguments'], started: false }) + } + return + } + const message = event.type === 'tool/result' ? record(data['message'], 'tool result message') : undefined + const id = text(message === undefined ? data['callId'] : message['toolCallId'], 'tool call id') + const pending = this.tools.get(id) + if (pending === undefined) throw new SessionFormatError(`${event.type} ${id} has no advertised tool lifecycle`) + if (message === undefined) { + if (pending.started || pending.name !== data['name'] || pending.arguments !== data['arguments']) { + throw new SessionFormatError(`tool/call ${id} does not match one advertised tool call`) + } + pending.started = true + } else { + if (!pending.started && !notStartedRepair(event, data, message, id)) { + throw new SessionFormatError(`tool/result ${id} is not the exact TOOL_NOT_STARTED repair`) + } + this.tools.delete(id) + } + } + + dispatch(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + this.requireTurn(event.type) + const id = text(data['subCallId'], 'PTC subCallId') + const root = text(data['rootCallId'], 'PTC rootCallId') + const parent = text(data['parentCallId'], 'PTC parentCallId') + const existing = this.dispatches.get(id) + if (existing !== undefined && existing.data['rootCallId'] !== root) throw new SessionFormatError('PTC dispatch changes its rootCallId') + if (parent !== root && this.dispatches.get(parent)?.data['rootCallId'] !== root) throw new SessionFormatError('PTC parentCallId does not belong to rootCallId') + if (event.type === 'tool/ptc-dispatch-start') { + if (existing !== undefined) throw new SessionFormatError('PTC dispatch repeats subCallId') + this.dispatches.set(id, { data, settled: false }) + return + } + if (existing === undefined || existing.settled) throw new SessionFormatError('PTC dispatch has no unique start') + if (['rootCallId', 'parentCallId', 'name', 'arguments'].some(key => !isDeepStrictEqual(existing.data[key], data[key]))) { + throw new SessionFormatError('PTC dispatch does not match its start') + } + existing.settled = true + } + + retry(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + const id = text(data['retryId'], 'retryId') + const attempt = sessionFormatCount(data['retry'], 'retry') + if (event.type === 'llm/retry-started') { + const scheduled = this.retries.find(item => item['retryId'] === id && item['retry'] === attempt) + if (scheduled === undefined) throw new SessionFormatError('llm/retry-started pairs no prior scheduled attempt') + if (scheduled['turn'] !== data['turn'] || scheduled['step'] !== data['step']) throw new SessionFormatError('llm/retry-started changes scheduled coordinates') + const key = JSON.stringify([id, attempt]) + if (this.startedRetries.has(key)) throw new SessionFormatError('llm/retry-started repeats one scheduled attempt') + this.startedRetries.add(key) + return + } + if (this.turn === null || data['turn'] !== this.turn || data['step'] !== (this.step ?? this.nextStep - 1)) { + throw new SessionFormatError('llm/retry does not match the current turn and step') + } + if (data['provider'] !== this.provider) throw new SessionFormatError('llm/retry provider does not match the open request/header') + const prior = this.retries.findLast(item => ['turn', 'step', 'provider', 'policyKey'].every(key => item[key] === data[key])) + if (attempt !== (prior === undefined ? 1 : sessionFormatCount(prior['retry'], 'prior retry') + 1)) throw new SessionFormatError('llm/retry skips its policy attempt sequence') + if (prior === undefined ? this.retries.some(item => item['retryId'] === id) : prior['retryId'] !== id) { + throw new SessionFormatError('llm/retry must keep one retryId per policy chain') + } + this.retries.push(data) + } + + compact(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + if (event.type === 'compaction/prune' || event.type === 'compaction/summary') this.span(event, data) + if (event.type === 'compaction/prune') return + if (event.type === 'compaction/start') { + if (this.compaction !== undefined) throw new SessionFormatError('compaction/start overlaps an open compaction') + const owner = data['turn'] === null ? null : sessionFormatCount(data['turn'], 'compaction turn') + if (owner !== this.turn) throw new SessionFormatError('compaction/start does not match the open turn') + this.compaction = { id: text(data['compactionId'], 'compactionId'), command: data['sourceCommandId'], turn: owner, seq: event.seq, summarized: false } + return + } + const current = this.compactionOwner(data, event.type) + if (current.turn !== this.turn) throw new SessionFormatError(`${event.type} does not match the open turn`) + if (event.type === 'compaction/summary') { + if (current.summarized) throw new SessionFormatError('compaction/summary repeats') + current.summarized = true + } else { + if (data['turn'] !== current.turn) throw new SessionFormatError('compaction/end changes its owner turn') + if (data['error'] === undefined && !current.summarized) throw new SessionFormatError('successful compaction/end requires one summary') + this.compaction = undefined + } + } + + compactionOwner(data: SessionFormatJsonObject, subject: string): Compaction { + if (this.compaction === undefined || this.compaction.id !== data['compactionId'] || this.compaction.command !== data['sourceCommandId']) { + throw new SessionFormatError(`${subject} has no matching compaction/start`) + } + return this.compaction + } + + span(event: SessionFormatEvent, data: SessionFormatJsonObject): void { + const range = record(data['shadowedRange'], 'compaction shadowedRange') + const start = this.surface.indexOf(earlier(range['start'], event.seq, 'compaction range start')) + const end = this.surface.indexOf(earlier(range['end'], event.seq, 'compaction range end')) + const seqs = array(data['shadowedSeqs'], 'compaction shadowedSeqs') + if (start < 0 || end < start || !isDeepStrictEqual(this.surface.slice(start, end + 1), seqs)) { + throw new SessionFormatError(`${event.type} shadowedSeqs do not name an exact current surface span`) + } + if (this.protectedHead !== undefined && seqs.includes(this.protectedHead)) throw new SessionFormatError('compaction cannot shadow the protected system head') + } + + accept(event: SessionFormatEvent): void { + if (!this.knownEventTypes.has(event.type) || !RELATIONSHIP_TYPES.has(event.type)) return + const data = record(event.data, event.type) + if (STEP_EVENT_TYPES.has(event.type)) this.requireStep(event, data) + if (event.type.startsWith('turn/') && this.compaction !== undefined && !this.orphanCompactions.has(this.compaction.seq)) { + throw new SessionFormatError(`${event.type} crosses an open compaction`) + } + this.foldSurface(event) + switch (event.type) { + case 'turn/start': + if (this.turn !== null || data['turn'] !== this.nextTurn) throw new SessionFormatError('turn/start does not open the expected turn') + this.turn = this.nextTurn + this.nextStep = 1 + this.tools.clear() + break + case 'turn/end': + if (this.turn === null || data['turn'] !== this.turn || this.step !== null) throw new SessionFormatError('turn/end does not match the open turn with no open step') + this.closeTools(event.type) + this.turn = null + this.nextTurn += 1 + break + case 'step/start': + if (this.turn === null || data['turn'] !== this.turn || this.step !== null || data['step'] !== this.nextStep) throw new SessionFormatError('step/start does not match the open turn and next step') + this.step = this.nextStep + break + case 'step/end': + this.requireStep(event, data) + this.closeTools(event.type) + this.step = null + this.nextStep += 1 + break + case 'assistant/message': case 'tool/call': case 'tool/result': this.tool(event, data); break + case 'developer/message': this.developer(event, data); break + case 'request/header': + this.requireTurn(event.type) + this.provider = record(record(data['header'], 'request header')['config'], 'request config')['provider'] + break + case 'request/context': this.requireTurn(event.type); break + case 'tool/ptc-dispatch-start': case 'tool/ptc-dispatch': this.dispatch(event, data); break + case 'llm/retry': case 'llm/retry-started': this.retry(event, data); break + case 'session/title': case 'session/title-llm-request': titleSources(this.artifact.events, event, data, this.knownEventTypes); break + case 'command/run': { + const id = text(data['commandId'], 'commandId') + if (this.commands.has(id)) throw new SessionFormatError(`command/run repeats commandId ${id}`) + this.commands.add(id) + break + } + case 'command/done': { + if (!this.commands.has(text(data['commandId'], 'commandId'))) throw new SessionFormatError('command/done has no prior command/run') + if (data['sourceEventSeq'] !== undefined) { + const source = this.artifact.events[earlier(data['sourceEventSeq'], event.seq, 'command sourceEventSeq')] + if (data['kind'] !== 'success' || source?.type === 'command/run' || source?.type === 'command/done') throw new SessionFormatError('command/done has invalid sourceEventSeq') + } + break + } + case 'compaction/start': case 'compaction/summary': case 'compaction/end': case 'compaction/prune': this.compact(event, data); break + case 'user/message': { + const source = record(data['source'], 'user message source') + if (event['surfaceOp'] !== 'append' && source['kind'] === 'compact-checkpoint') this.compactionOwner(source, 'compaction checkpoint') + break + } + case 'session/end-seed': this.compaction = undefined; break + } + } +} + +function notStartedRepair( + event: SessionFormatEvent, data: SessionFormatJsonObject, message: SessionFormatJsonObject, callId: string, +): boolean { + const error = record(data['error'], 'not-started error') + if (error['name'] !== 'ToolNotStartedError' || error['code'] !== 'TOOL_NOT_STARTED' || message['isError'] !== true || event['sourceEventSeqs'] !== undefined) return false + const id = text(message['id'], 'not-started message id') + // Fork-specific fields and identity are checked by assertV4ForkResult before relationships. + if (id.startsWith(`forked-tool-result-${callId}-`)) return true + const prefix = `interrupted-tool-result-${callId}-` + const suffix = id.slice(prefix.length) + const content = array(message['content'], 'not-started content') + const block = content[0] + return id.startsWith(prefix) && /^(0|[1-9]\d*)$/.test(suffix) && Number.isSafeInteger(Number(suffix)) + && content.length === 1 && isSessionFormatJsonObject(block) && block['type'] === 'text' + && block['text'] === 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.' +} + +function titleSources( + events: readonly SessionFormatEvent[], event: SessionFormatEvent, data: SessionFormatJsonObject, knownEventTypes: ReadonlySet, +): void { + const references = array(data['messageSeqs'], 'title messageSeqs') + if (event.type === 'session/title' && (references.length === 0) !== (record(data['source'], 'title source')['kind'] === 'user')) { + throw new SessionFormatError('session/title messageSeqs must be empty exactly for a user title') + } + const seen = new Set() + for (const value of references) { + const seq = earlier(value, event.seq, 'title messageSeqs') + const source = events[seq] + if (seen.has(seq) || source?.type !== 'user/message' || !knownEventTypes.has(source.type) || record(record(source.data, 'title input')['source'], 'title input source')['kind'] !== 'user') { + throw new SessionFormatError(`${event.type} messageSeqs must cite distinct earlier human user/message events`) + } + seen.add(seq) + } + if (event.type !== 'session/title-llm-request') return + const messages = array(data['messages'], 'title messages') + const message = record(messages[0], 'title message') + const content = array(message['content'], 'title content') + const block = content[0] + if (references.length === 0 || messages.length !== 1 || message['role'] !== 'user' + || record(message['source'], 'title source')['kind'] !== 'dsh-session-title-llm' + || content.length !== 1 || !isSessionFormatJsonObject(block) || block['type'] !== 'text') { + throw new SessionFormatError('session/title-llm-request messages do not represent messageSeqs') + } +} + +/** + * Validate native V4 lifecycle and ownership facts without rewriting any event. + * @param artifact - artifact whose V4 envelopes and messages have been admitted. + * @param knownEventTypes - installed event types whose payloads this reader interprets. + */ +export function assertV4LifecycleRelationships(artifact: SessionFormatArtifact, knownEventTypes: ReadonlySet): void { + const state = new Relationships(artifact, knownEventTypes) + for (const event of artifact.events) state.accept(event) +} diff --git a/packages/session/session-format-v3-to-v4/src/retired-syntax.ts b/packages/session/session-format-v3-to-v4/src/retired-syntax.ts new file mode 100644 index 0000000000..13d62c45f5 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/retired-syntax.ts @@ -0,0 +1,75 @@ +/** Retired native syntax remains a hard refusal even after a recoverable physical-row failure. */ + +import { SessionFormatError, SessionFormatUnsupportedMigrationError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' + +function assertBlock(block: unknown, subject: string): void { + if (isSessionFormatJsonObject(block) && block['type'] === 'tool-result') { + throw new SessionFormatError(`${subject} must not contain a released tool-result wrapper`) + } +} + +function assertContent(content: unknown, subject: string): void { + if (Array.isArray(content)) content.forEach((block) => { assertBlock(block, subject) }) +} + +function assertMessageContent(message: unknown, subject: string): void { + if (isSessionFormatJsonObject(message)) assertContent(message['content'], subject) +} + +/** + * Refuse retired headers, PTC tags, and tool-result blocks in interpreted content slots. + * Tool arguments, replay state, schema parameters, and nested extension values remain opaque. + * @param row - parsed physical row or complete native logical event. + */ +export function assertV4RetiredSyntax(row: unknown): void { + if (!isSessionFormatJsonObject(row)) return + if ((row['type'] === 'tool/code-dispatch-start' || row['type'] === 'tool/code-dispatch') && row['ignorable'] !== true) { + throw new SessionFormatUnsupportedMigrationError(`format v4 rejects retired event type ${row['type']}`) + } + const data = row['data'] + if (row['type'] === 'request/header') { + if (!isSessionFormatJsonObject(data) || !isSessionFormatJsonObject(data['header'])) { + throw new SessionFormatError('format v4 request/header requires data and header objects') + } + if (Object.hasOwn(data['header'], 'system')) { + throw new SessionFormatError('format v4 request/header rejects retired header.system') + } + return + } + if (!isSessionFormatJsonObject(data)) return + const subject = `format v4 ${String(row['type'])} at seq ${String(row['seq'])} content` + switch (row['type']) { + case 'user/message': + assertContent(data['content'], subject) + break + case 'developer/message': + case 'assistant/message': + case 'team/message/queued': + assertMessageContent(data['message'], subject) + break + case 'agent/inbox/spliced': + case 'session/title-llm-request': { + const messages = data[row['type'] === 'agent/inbox/spliced' ? 'inserted' : 'messages'] + if (Array.isArray(messages)) messages.forEach((message) => { assertMessageContent(message, subject) }) + break + } + case 'compaction/summary': + assertContent(data['summary'], subject) + assertContent(data['rawOutput'], subject) + break + case 'tool/ptc-dispatch': + assertContent(data['content'], subject) + break + } + if ((row['type'] === 'assistant/message' || row['type'] === 'assistant/attempt') && Array.isArray(data['stream'])) { + for (const entry of data['stream']) { + if (!isSessionFormatJsonObject(entry) || entry['type'] !== 'chunk') continue + const chunk = entry['chunk'] + if (!isSessionFormatJsonObject(chunk)) continue + if (chunk['type'] === 'block-end') assertBlock(chunk['block'], subject) + if (chunk['type'] === 'block-start' && chunk['blockType'] === 'tool-result') { + throw new SessionFormatError(`${subject} must not contain a released tool-result wrapper`) + } + } + } +} diff --git a/packages/session/session-format-v3-to-v4/src/sources.ts b/packages/session/session-format-v3-to-v4/src/sources.ts new file mode 100644 index 0000000000..3c6a288613 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/sources.ts @@ -0,0 +1,106 @@ +/** Released V3 plugin-source conversion and declared message traversal. */ + +import { SessionFormatError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' + +/** + * Visit only messages carried by first-party event payloads. + * @param event - source or target logical event. + * @param transform - message transform preserving unchanged identity. + * @returns the event sharing all untouched payloads. + */ +export function mapEventMessages( + event: SessionFormatEvent, + transform: (message: SessionFormatJsonObject) => SessionFormatJsonObject, +): SessionFormatEvent { + const data = event.data + if (!isSessionFormatJsonObject(data)) return event + if (event.type === 'user/message') { + const message = transform(data) + return message === data ? event : { ...event, data: message } + } + if (event.type === 'developer/message' || event.type === 'system/message' || event.type === 'assistant/message' || event.type === 'tool/result') { + if (!isSessionFormatJsonObject(data['message'])) throw new SessionFormatError(event.type + ' requires a message') + const message = transform(data['message']) + return message === data['message'] ? event : { ...event, data: { ...data, message } } + } + const key = event.type === 'agent/inbox/spliced' ? 'inserted' : event.type === 'session/title-llm-request' ? 'messages' : undefined + if (key === undefined) return event + const messages = data[key] + if (!Array.isArray(messages)) throw new SessionFormatError(event.type + ' requires message array') + const mapped = (messages as readonly SessionFormatJsonValue[]).map((message) => { + if (!isSessionFormatJsonObject(message)) throw new SessionFormatError(event.type + ' requires message objects') + return transform(message) + }) + return mapped.every((message, index) => message === messages[index]) ? event : { ...event, data: { ...data, [key]: mapped } } +} + +/** Released V3 plugin names whose current producer kind is not the plugin string. */ +const RENAMED_PRODUCERS: Readonly> = Object.freeze({ + 'compact': 'compact-checkpoint', + 'tools-code-mode': 'ptc-mode', + 'tools-ptc': 'ptc-mode', + 'dsh-compaction-basic': 'compact-basic', + '@deepseek-ai/dsh-system-prompt': 'runtime-context', +}) + +/** First-party V3 plugin identities that intentionally keep their current kind. */ +const RELEASED_SAME_NAME_PRODUCERS: ReadonlySet = new Set([ + 'agent-instructions', 'session-reference', 'team-message', 'goal', + 'skill-invocation', 'skill-catalog', 'coordinator', 'subagent-report', + 'subagent-settled', 'webhook', 'agent-message', 'model-selection', + 'plan-mode', 'time-context', 'tmux-context', 'user-approval', + 'repeat-tool-reminder', 'tool-cordis', 'cordis-host-runner', 'tool-goal', + 'tool-jobs', 'hooks-codex', 'hooks-claude-code', 'schedule', + 'dsh-session-title-llm', +]) + +/** Resolve the current producer kind for one released V3 plugin string. */ +function producerKind(plugin: string, role: SessionFormatJsonValue | undefined): string { + if (plugin === '@deepseek-ai/dsh-system-prompt' && role === 'system') return 'system-prompt' + const renamed = Object.hasOwn(RENAMED_PRODUCERS, plugin) ? RENAMED_PRODUCERS[plugin] : undefined + if (renamed !== undefined) return renamed + if (RELEASED_SAME_NAME_PRODUCERS.has(plugin)) return plugin + return `plugin:${plugin}` +} + +/** + * Lift one released V3 plugin source into the current producer-owned shape. + * @param source - source record whose `kind` is `'plugin'`. + * @param seq - event seq for diagnostics. + * @param role - carried message role for role-sensitive renames. + * @returns a copy whose kind is the producer's own kind and whose `plugin` field is dropped. + */ +export function rewritePluginSource( + source: SessionFormatJsonObject, + seq: number, + role: SessionFormatJsonValue | undefined, +): SessionFormatJsonObject { + const plugin = source['plugin'] + if (typeof plugin !== 'string') { + throw new SessionFormatError( + `plugin source at seq ${seq} is not canonical: plugin requires a string`, + ) + } + const kind = producerKind(plugin, role) + if (Object.keys(source).length === 2) return { kind } + return Object.fromEntries(Object.entries(source) + .filter(([key]) => key !== 'plugin') + .map(([key, item]) => [key, key === 'kind' ? kind : item])) +} + +/** + * Convert released plugin wrappers while retaining every direct source kind and its metadata. + * @param source - decoded V3 message source. + * @param seq - event sequence for diagnostics. + * @param role - enclosing message role for role-sensitive producer mappings. + * @returns the converted source with every non-identity field preserved. + */ +export function rewriteV3MessageSource( + source: SessionFormatJsonObject, seq: number, role: SessionFormatJsonValue | undefined, +): SessionFormatJsonObject { + const kind = source['kind'] + if (typeof kind !== 'string' || kind.length === 0) throw new SessionFormatError(`message source at seq ${seq} requires a nonempty kind`) + if (kind === 'plugin') return rewritePluginSource(source, seq, role) + return source +} diff --git a/packages/session/session-format-v3-to-v4/src/system-message.ts b/packages/session/session-format-v3-to-v4/src/system-message.ts new file mode 100644 index 0000000000..f2a2ed1378 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/system-message.ts @@ -0,0 +1,64 @@ +/** Native system-message fields checked before physical recovery can discard a row. */ + +import { SessionFormatError, isSessionFormatJsonObject, sessionFormatCount } from '@deepseek-ai/dsh-session-format' + +function record(value: unknown, subject: string): Readonly> { + if (!isSessionFormatJsonObject(value)) throw new SessionFormatError(`format v4 ${subject} requires an object`) + return value +} + +function string(value: unknown, subject: string, nonempty = false): void { + if (typeof value !== 'string' || nonempty && value.length === 0) throw new SessionFormatError(`format v4 ${subject} requires a string${nonempty ? ' with content' : ''}`) +} + +function positive(value: unknown, subject: string): void { + if (sessionFormatCount(value, subject) === 0) throw new SessionFormatError(`format v4 ${subject} must be positive`) +} + +function image(value: unknown): void { + const attachment = record(value, 'system image attachment') + string(attachment['attachmentId'], 'system image attachmentId', true) + if (!['image/png', 'image/jpeg', 'image/webp', 'image/gif'].includes(attachment['mediaType'] as string)) throw new SessionFormatError('format v4 system image requires a supported mediaType') + sessionFormatCount(attachment['bytes'], 'system image bytes') + positive(attachment['width'], 'system image width') + positive(attachment['height'], 'system image height') + if (attachment['name'] !== undefined) string(attachment['name'], 'system image name') + if (attachment['originalDimensions'] !== undefined) { + const original = record(attachment['originalDimensions'], 'system image originalDimensions') + positive(original['width'], 'system image original width') + positive(original['height'], 'system image original height') + } +} + +/** + * Validate system fields independently of historical message representations; preserve additional JSON fields. + * @param row - complete logical event or parsed physical row before corruption recovery. + */ +export function assertV4SystemMessageFields(row: unknown): void { + if (!isSessionFormatJsonObject(row) || row['type'] !== 'system/message') return + const data = record(row['data'], 'system/message data') + positive(data['turn'], 'system/message turn') + positive(data['step'], 'system/message step') + const message = record(data['message'], 'system message') + string(message['id'], 'system message id', true) + if (message['role'] !== 'system') throw new SessionFormatError('format v4 system message requires system role') + const content = message['content'] + if (!Array.isArray(content)) throw new SessionFormatError('format v4 system message requires content array') + for (const value of content) { + const block = record(value, 'system content block') + string(block['type'], 'system content type', true) + switch (block['type']) { + case 'text': case 'reasoning': string(block['text'], 'system content text'); break + case 'tool-call': + string(block['id'], 'system tool-call id', true) + string(block['name'], 'system tool-call name', true) + string(block['arguments'], 'system tool-call arguments') + break + case 'image': image(block['attachment']); break + case 'tool-result': throw new SessionFormatError('format v4 system content rejects retired tool-result wrappers') + default: + // ContentBlockMap is merge-extensible; only known block fields are interpreted here. + break + } + } +} diff --git a/packages/session/session-format-v3-to-v4/src/testing/validation.ts b/packages/session/session-format-v3-to-v4/src/testing/validation.ts new file mode 100644 index 0000000000..08ec7fa8c6 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/testing/validation.ts @@ -0,0 +1,15 @@ +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatArtifact } from '@deepseek-ai/dsh-session-format' +import { releasedV4SessionFormatCodec } from '../codec.ts' + +/** + * Validate an artifact through the native codec without vocabulary-aware restoration. + * @param artifact - current-generation artifact to encode and decode. + */ +export function assertReleasedV4Artifact(artifact: SessionFormatArtifact): void { + const codec = releasedV4SessionFormatCodec + const decoder = codec.createDecoder(codec.encodeHeader(artifact.header, artifact.inheritedEventCount), 'strict') + const output = new SessionFormatEventCollector() + for (const event of artifact.events) decoder.decodeRow(codec.encodeEvent(event), output) + decoder.finish(output) +} diff --git a/packages/session/session-format-v3-to-v4/src/tool-role.ts b/packages/session/session-format-v3-to-v4/src/tool-role.ts new file mode 100644 index 0000000000..239a299fdc --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/tool-role.ts @@ -0,0 +1,112 @@ +/** First-class tool-role messages in the V4 representation. */ + +import { SessionFormatError, SessionFormatUnsupportedMigrationError, isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' + +const WRAPPER_FIELDS = new Set(['type', 'toolCallId', 'content', 'isError']) +const MESSAGE_FIELDS = new Set(['id', 'role', 'source', 'content']) + +/** Preserve unknown fields without merging their original message and result owners. */ +function extensionFields( + value: Record, fields: ReadonlySet, owner: 'message' | 'result', +): Record { + return Object.fromEntries(Object.entries(value).filter(([key]) => !fields.has(key)) + .map(([key, field]) => [`plugin:${owner}:${key}`, field])) +} + +function resultContent(value: SessionFormatJsonValue | undefined, subject: string): SessionFormatJsonValue[] { + if (!Array.isArray(value)) throw new SessionFormatError(`${subject} tool-result content must be an array`) + if (value.some(block => isSessionFormatJsonObject(block) && block['type'] === 'tool-result')) { + throw new SessionFormatUnsupportedMigrationError( + `${subject} contains a nested tool-result unsupported by this converter`, + ) + } + return value as SessionFormatJsonValue[] +} + +/** + * Lift one released-V3 wrapper tool/result row into the first-class V4 message. + * Validate the wrapper before dropping it so malformed historical content is + * rejected instead of being silently truncated. + * @param event - released wrapper tool/result event. + * @returns the same event with a first-class tool-role message. + * @throws {SessionFormatError} when the wrapper, tool source, content, or error flag is malformed. + * @throws {SessionFormatUnsupportedMigrationError} when the result contains another result. + */ +export function liftToolResult(event: SessionFormatEvent): SessionFormatEvent { + if (event.type !== 'tool/result' || !isSessionFormatJsonObject(event.data)) return event + const data = event.data + const message = data['message'] + if (!isSessionFormatJsonObject(message) || message['role'] !== 'user') return event + const source = message['source'] + const callId = isSessionFormatJsonObject(source) ? source['callId'] : undefined + const content = message['content'] + const block = Array.isArray(content) && content.length === 1 + ? (content as readonly SessionFormatJsonValue[])[0] + : undefined + const wrapper = isSessionFormatJsonObject(block) ? block : undefined + const id = message['id'] + if (typeof id !== 'string' || id.length === 0 + || !isSessionFormatJsonObject(source) || source['kind'] !== 'tool' + || typeof callId !== 'string' || callId.length === 0 + || wrapper === undefined || wrapper['type'] !== 'tool-result' + || wrapper['toolCallId'] !== callId) { + throw new SessionFormatError(`format v3 ${event.type} at seq ${event.seq} requires exactly one tool-result wrapper matching its tool source`) + } + const isError = wrapper['isError'] + if (isError !== undefined && typeof isError !== 'boolean') { + throw new SessionFormatError(`format v3 ${event.type} at seq ${event.seq} tool-result isError must be boolean`) + } + const targetMessage: Record = { + role: 'tool', + source, + toolCallId: callId, + content: resultContent(wrapper['content'], `format v3 ${event.type} at seq ${event.seq}`), + ...(isError === undefined ? {} : { isError }), + id, + ...extensionFields(message, MESSAGE_FIELDS, 'message'), + ...extensionFields(wrapper, WRAPPER_FIELDS, 'result'), + } + return { ...event, data: { ...data, message: targetMessage } } +} + +/** + * Validate the native V4 first-class tool-role message of one tool/result row. + * @param event - canonical V4 event. + * @throws {SessionFormatError} when the row is not an exact first-class tool result. + */ +export function assertV4ToolResultMessage(event: SessionFormatEvent): void { + if (event.type !== 'tool/result') return + const subject = `format v4 ${event.type} at seq ${event.seq}` + const data = event.data + if (!isSessionFormatJsonObject(data)) throw new SessionFormatError(`${subject} data must be an object`) + const message = data['message'] + if (!isSessionFormatJsonObject(message)) throw new SessionFormatError(`${subject} message must be an object`) + const id = message['id'] + const role = message['role'] + const toolCallId = message['toolCallId'] + const source = message['source'] + const isError = message['isError'] + const content = message['content'] + const sourceCallId = isSessionFormatJsonObject(source) ? source['callId'] : undefined + if (typeof id !== 'string' || id.length === 0) { + throw new SessionFormatError(`${subject} requires a first-class message with a string id`) + } + if (role !== 'tool') throw new SessionFormatError(`${subject} requires a tool-role message`) + if (typeof toolCallId !== 'string' || toolCallId.length === 0 || sourceCallId !== toolCallId) { + throw new SessionFormatError(`${subject} requires toolCallId matching its tool source`) + } + if (!isSessionFormatJsonObject(source) || source['kind'] !== 'tool') { + throw new SessionFormatError(`${subject} requires a tool source`) + } + if (!Array.isArray(content)) throw new SessionFormatError(`${subject} requires array content`) + if (content.some(block => isSessionFormatJsonObject(block) && block['type'] === 'tool-result')) { + throw new SessionFormatError(`${subject} content must not contain a released tool-result wrapper`) + } + if (isError !== undefined && typeof isError !== 'boolean') { + throw new SessionFormatError(`${subject} isError must be boolean when present`) + } + if (data['error'] !== undefined && isError !== true) { + throw new SessionFormatError(`${subject} carries error metadata for a non-error tool result`) + } +} diff --git a/packages/session/session-format-v3-to-v4/src/validation.ts b/packages/session/session-format-v3-to-v4/src/validation.ts new file mode 100644 index 0000000000..8c0e74d61d --- /dev/null +++ b/packages/session/session-format-v3-to-v4/src/validation.ts @@ -0,0 +1,130 @@ +/** Native V4 metadata and generation-owned relationship validation. */ + +import { isAbsolute } from 'node:path' +import { SessionFormatError, SessionFormatUnsupportedMigrationError, isSessionFormatJsonObject, sessionFormatCount } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatArtifact, SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { assertV4DeveloperData } from './developer.ts' +import { assertV4LifecycleRelationships } from './relationships.ts' +import { assertV4MessageSources } from './message-sources.ts' +import { catalogFact } from './facts.ts' +import { assertV4RetiredSyntax } from './retired-syntax.ts' +import { assertV4SystemMessageFields } from './system-message.ts' +import { assertV4ForkResult } from './fork-result.ts' +import { assertV4ToolResultMessage } from './tool-role.ts' + +/** + * Validate the exact native V4 logical header. + * @param header - decoded or otherwise untrusted V4 Session header candidate. + */ +export function assertReleasedV4Header(header: unknown): void { + if (!isSessionFormatJsonObject(header) || header['version'] !== 4) throw new SessionFormatError('expected format v4 header') + const required = ['version', 'id', 'createdAt', 'isSeeded', 'delegationDepth'] + const allowed = new Set([...required, 'cwd', 'parentSession', 'origin', 'agentPreset']) + const missing = required.find(key => !Object.hasOwn(header, key)) + const unexpected = Object.keys(header).find(key => !allowed.has(key)) + if (missing !== undefined) throw new SessionFormatError(`format v4 header lacks required field ${missing}`) + if (unexpected !== undefined) throw new SessionFormatError(`format v4 header has unexpected field ${unexpected}`) + if (typeof header.id !== 'string') throw new SessionFormatError('format v4 header id must be a string') + sessionFormatCount(header.createdAt, 'format v4 header createdAt') + sessionFormatCount(header.delegationDepth, 'format v4 header delegationDepth') + if (typeof header.isSeeded !== 'boolean') throw new SessionFormatError('format v4 header isSeeded must be boolean') + if (header.cwd !== undefined && (typeof header.cwd !== 'string' || !isAbsolute(header.cwd))) { + throw new SessionFormatError('format v4 header cwd must be absolute') + } + for (const key of ['parentSession', 'agentPreset']) { + if (header[key] !== undefined && typeof header[key] !== 'string') { + throw new SessionFormatError(`format v4 header ${key} must be a string`) + } + } + if (header.origin !== undefined && header.origin !== 'subagent') { + throw new SessionFormatError('format v4 header origin must be "subagent"') + } +} + +/** + * Validate V4 inheritance, vocabulary, native message admission, and + * lifecycle, compaction, tool, retry, title, command, catalog, and delivery ownership. + * Installed Session restoration owns common event envelopes and message acceptance. + * @param artifact - complete detached V4 artifact. + * @param knownEventTypes - event types understood by the installed Session package. + * @returns the same validated artifact and event objects. + */ +export function restoreReleasedV4Artifact(artifact: SessionFormatArtifact, knownEventTypes: ReadonlySet): SessionFormatArtifact { + assertReleasedV4Header(artifact.header) + const cut = sessionFormatCount(artifact.inheritedEventCount, 'format v4 inherited event count') + if (cut > artifact.events.length) throw new SessionFormatError('format v4 inherited event count exceeds its events') + if (!artifact.header.isSeeded && cut !== 0) throw new SessionFormatError('unseeded format v4 Session has inherited events') + let lastInheritedMarker: number | undefined + for (const [index, event] of artifact.events.entries()) { + if (!knownEventTypes.has(event.type) && event['ignorable'] !== true) { + throw new SessionFormatUnsupportedMigrationError( + `format v4 contains unknown event type ${JSON.stringify(event.type)} at seq ${index}`, + ) + } + if (event.seq !== index) throw new SessionFormatError(`format v4 event ${index} is not dense`) + if (!knownEventTypes.has(event.type)) continue + assertV4RetiredSyntax(event) + assertV4SystemMessageFields(event) + assertV4ToolResultMessage(event) + assertV4ForkResult(event) + if (event.type === 'session/end-seed' && isSessionFormatJsonObject(event.data) + && event.data['inherited'] === true) lastInheritedMarker = index + } + if (artifact.header.isSeeded && lastInheritedMarker !== cut) { + throw new SessionFormatError('format v4 seeded header disagrees with its last inherited end-seed marker') + } + if (!artifact.header.isSeeded && lastInheritedMarker !== undefined) { + throw new SessionFormatError('format v4 unseeded Session contains an inherited end-seed marker') + } + assertReleasedV4Relationships(artifact, knownEventTypes) + return artifact +} + +/** + * Validate delivery generation and active-generation coordinates before evaluating ownership. + * @param event - decoded event whose delivery payload may be inspected. + * @param currentVersion - generation whose watermark coordinates are active. + * @returns the active delivery's nonempty Session id, or undefined for other events and generations. + */ +export function validateDeliveryAccepted(event: SessionFormatEvent, currentVersion: 3 | 4): string | undefined { + if (event.type !== 'session-log-deepseek/delivery-accepted') return undefined + const data = event.data + if (!isSessionFormatJsonObject(data)) throw new SessionFormatError('delivery-accepted data must be an object') + const version = sessionFormatCount(data['sessionFormatVersion'] === undefined ? 0 : data['sessionFormatVersion'], 'delivery sessionFormatVersion') + if (version !== currentVersion) return undefined + const throughSeq = sessionFormatCount(data['throughSeq'], 'delivery throughSeq') + if (throughSeq >= event.seq) throw new SessionFormatError('delivery throughSeq must precede its marker') + const id = data['sessionId'] + if (typeof id !== 'string' || id.length === 0) throw new SessionFormatError('delivery requires a nonempty Session id') + return id +} + +/** + * Validate native developer fields, message sources, lifecycle, catalog, and delivery + * relationships without changing event vocabulary or tail recovery. + * The owning admission stage rejects unknown required events; + * unknown ignorable records retain their uninterpreted payloads. + * @param artifact - decoded artifact with its final inherited cut. + * @param knownEventTypes - installed event types whose payloads this reader interprets. + */ +export function assertReleasedV4Relationships(artifact: SessionFormatArtifact, knownEventTypes: ReadonlySet): void { + const ids = new Set() + for (const event of artifact.events) { + if (!knownEventTypes.has(event.type)) continue + assertV4DeveloperData(event) + assertV4MessageSources(event) + const deliveryId = validateDeliveryAccepted(event, 4) + if (deliveryId !== undefined + && !(artifact.header.parentSession !== undefined && event.seq < artifact.inheritedEventCount) + && deliveryId !== artifact.header.id) { + throw new SessionFormatError('current-generation delivery marker names the wrong Session') + } + if (event.type === 'subagent/catalog' && event.seq >= artifact.inheritedEventCount) { + const fact = catalogFact(event.data) + const id = fact['childId'] as string + if (ids.has(id)) throw new SessionFormatError(`duplicate catalog child ${id}`) + ids.add(id) + } + } + assertV4LifecycleRelationships(artifact, knownEventTypes) +} diff --git a/packages/session/session-format-v3-to-v4/tests/attribution.spec.ts b/packages/session/session-format-v3-to-v4/tests/attribution.spec.ts new file mode 100644 index 0000000000..34eaa4b4b6 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/attribution.spec.ts @@ -0,0 +1,41 @@ +/** Unknown producer attribution survives the native codec and detached Session reader. */ +import { describe, expect, it } from 'vitest' +import { Session, SessionId, SessionLogOffset } from '@deepseek-ai/dsh-session' +import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { releasedV4SessionFormatCodec as codec, restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { version: 4, id: 'unknown-attribution', createdAt: 1, isSeeded: false, delegationDepth: 0 } + +describe('uninstalled producer attribution', () => { + it.each(['user', 'developer'] as const)('preserves %s source metadata through decoding, adoption and derivation', (role) => { + const message = { + id: 'attributed-message', role, + source: { kind: 'external-attribution', location: { file: 'notes.txt', lines: [2, 5] }, enabled: false }, + content: [{ type: 'text', text: 'Retain this context.' }], + } + const input: SessionFormatEvent[] = [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'step/start', seq: 1, time: 2, data: { turn: 1, step: 1 } }, + { type: `${role}/message`, seq: 2, time: 3, surfaceOp: 'append', data: role === 'user' ? message : { turn: 1, step: 1, message } }, + { type: 'step/end', seq: 3, time: 4, data: { turn: 1, step: 1 } }, + { type: 'turn/end', seq: 4, time: 5, data: { turn: 1, reason: { kind: 'completed' } } }, + ] + const physical = input.map(event => JSON.stringify(codec.encodeEvent(event))) + const output = new SessionFormatEventCollector() + const decoder = codec.createDecoder(codec.encodeHeader(header, 0), 'strict') + for (const row of physical) decoder.decodeRow(JSON.parse(row), output) + const inheritedEventCount = decoder.finish(output) + const artifact = { header, events: output.values, inheritedEventCount } + const restored = restoreReleasedV4Artifact(artifact, new Set(input.map(event => event.type))) + expect(restored.events).toEqual(input) + // The format reader validates stored JSON; adoption validates the current Session fields. + const session = Session.fromRestore( + SessionId(header.id), restored.events as readonly SessionEvent[], restored.header as unknown as SessionHeader, + SessionLogOffset(restored.inheritedEventCount), 'detached', + ) + expect(session.deriveMessages()).toEqual([message]) + expect(restored.events.map(event => JSON.stringify(codec.encodeEvent(event)))).toEqual(physical) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/canonical.spec.ts b/packages/session/session-format-v3-to-v4/tests/canonical.spec.ts new file mode 100644 index 0000000000..ad670986bd --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/canonical.spec.ts @@ -0,0 +1,111 @@ +import { describe, expect, it } from 'vitest' +import { createSessionFormatCatalogWithChildren, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatArtifact, SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { releasedV4SessionFormatCodec, restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { type: 'session', version: 2, id: 'canonical-v4', createdAt: 1, isSeeded: true, parentSession: 'parent', delegationDepth: 0 } +function source() { + const user = { id: 'context', role: 'user', source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, content: [{ type: 'text', text: 'context' }] } + const dispatch = { rootCallId: 'root', parentCallId: 'root', subCallId: 'child', name: 'test', arguments: { kind: 'plugin', plugin: 'tools-ptc' } } + const rows = [ + { type: 'turn/start', data: { turn: 1 } }, + { type: 'step/start', data: { turn: 1, step: 1 } }, + { type: 'request/header', data: { reason: 'initial', header: { config: { provider: 'mock', model: 'mock' }, system: 'system', tools: [] } } }, + { type: 'user/message', surfaceOp: 'append', data: user }, + { type: 'tool/code-dispatch-start', data: dispatch }, + { type: 'tool/code-dispatch', data: { ...dispatch, isError: false, content: [] } }, + { type: 'user/message', surfaceOp: { op: 'replace', start: 3, end: 3 }, sourceEventSeqs: [3], data: { ...user, id: 'replacement', source: { kind: 'plugin', plugin: 'tools-code-mode' } } }, + { type: 'request/header', data: { reason: 'change', header: { config: { provider: 'mock', model: 'mock' }, system: '' } } }, + { type: 'step/end', data: { turn: 1, step: 1 } }, + { type: 'turn/end', data: { turn: 1, reason: { kind: 'completed' } } }, + { type: 'session/end-seed', data: { inherited: true } }, + ] + return rows.map((row, seq) => ({ ...row, seq, time: seq + 1 })) as SessionFormatEvent[] +} +function migrated() { + const restore = createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const row of source()) restore.decodeRow(row) + return restore.finish() +} + +function reopen(artifact: SessionFormatArtifact) { + const header = sessionFormatCatalog.encodeCurrentHeader(artifact.header, artifact.inheritedEventCount) + const restore = sessionFormatCatalog.createRestore(header, { + recovery: 'strict', validation: 'current', + }) + for (const event of artifact.events) restore.decodeRow(sessionFormatCatalog.encodeCurrentEvent(event)) + return restore.finish() +} + +describe('canonical V4 integration', () => { + it('composes seeded systems, source ownership, PTC, canonical replacements and native round-trip', () => { + const target = migrated() + expect(target.header.version).toBe(4) + expect(target.inheritedEventCount).toBe(13) + const systems = target.events.filter(event => event.type === 'system/message') + expect(systems).toHaveLength(3) + for (const system of systems) expect(system.data).toMatchObject({ message: { role: 'system', source: { kind: 'system-prompt' } } }) + const users = target.events.filter(event => event.type === 'user/message') + expect(users[0]?.data).toMatchObject({ source: { kind: 'runtime-context' } }) + expect(users[1]).toMatchObject({ surfaceOp: { op: 'replace', startSeq: 5, endSeq: 5 }, sourceEventSeqs: [5], data: { source: { kind: 'ptc-mode' } } }) + expect(target.events.find(event => event.type === 'tool/ptc-dispatch')?.data).toMatchObject({ arguments: { kind: 'plugin', plugin: 'tools-ptc' } }) + const before = JSON.stringify(target) + expect(restoreReleasedV4Artifact(target, new Set(target.events.map(event => event.type)))).toBe(target) + expect(reopen(target)).toEqual(target) + expect(JSON.stringify(target)).toBe(before) + }) + + it.each([{ sourceEventSeqs: [] }, { surfaceOp: { op: 'replace', start: 0, end: 0 } }])('rejects noncanonical native metadata %j', (override) => { + const target = migrated() + const system = target.events.find(event => event.type === 'system/message')! + const bad = { ...system, ...override } + const invalid = { ...target, events: target.events.map(event => event === system ? bad : event) } + expect(() => reopen(invalid)).toThrow() + }) + + it('leaves common event and message validation to current Session restoration', () => { + const decoder = releasedV4SessionFormatCodec.createDecoder({ ...header, version: 4, isSeeded: false }, 'recoverable') + const output = new SessionFormatEventCollector() + decoder.decodeRow(null, output) + expect(decoder.finish(output)).toBe(0) + }) + + it('keeps earlier-generation delivery markers ignored and validates native current ownership', () => { + const marker = (version: number): SessionFormatEvent => ({ type: 'session-log-deepseek/delivery-accepted', seq: 0, time: 1, data: { sessionId: 'other', throughSeq: 0, sessionFormatVersion: version } }) + const { type: _type, ...logical } = header + const artifact = { header: { ...logical, version: 4, isSeeded: false }, inheritedEventCount: 0, events: [marker(3)] } + expect(restoreReleasedV4Artifact(artifact, new Set([marker(3).type]))).toBe(artifact) + expect(() => restoreReleasedV4Artifact({ ...artifact, events: [{ type: 'feedback/record', seq: 0, time: 1, ignorable: true, data: {} }, { ...marker(4), seq: 1 }] }, new Set(['feedback/record', marker(4).type]))).toThrow(/wrong Session/) + const reader = createSessionFormatCatalogWithChildren([]).createRestore({ ...header, version: 3, isSeeded: false }, { recovery: 'strict', validation: 'current' }) + reader.decodeRow({ type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }) + reader.decodeRow({ ...marker(3), seq: 1, time: 2 }) + expect(() => reader.finish()).toThrow(/wrong Session/) + }) + + it('retains native compaction checkpoint sources during restoration', () => { + const artifact: SessionFormatArtifact = { + header: { version: 4, id: 'compact-v4', createdAt: 1, isSeeded: false, delegationDepth: 0 }, + inheritedEventCount: 0, + events: [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'user/message', seq: 1, time: 2, data: { id: 'input', role: 'user', source: { kind: 'user' }, content: [{ type: 'text', text: 'input' }] }, surfaceOp: 'append' }, + { type: 'compaction/start', seq: 2, time: 3, data: { compactionId: 'compact-1', turn: 1 } }, + { type: 'compaction/summary', seq: 3, time: 4, data: { + compactionId: 'compact-1', summary: [{ type: 'text', text: 'summary' }], + shadowedRange: { start: 1, end: 1 }, shadowedSeqs: [1], shadowedTokenCount: 1, + provider: 'mock', model: 'mock', + } }, + { type: 'user/message', seq: 4, time: 5, data: { + id: 'checkpoint', role: 'user', + source: { kind: 'compact-checkpoint', compactionId: 'compact-1' }, + content: [{ type: 'text', text: 'summary' }], + }, surfaceOp: { op: 'replace', startSeq: 1, endSeq: 1 }, sourceEventSeqs: [2, 3, 1] }, + { type: 'compaction/end', seq: 5, time: 6, data: { compactionId: 'compact-1', turn: 1 } }, + { type: 'turn/end', seq: 6, time: 7, data: { turn: 1, reason: { kind: 'completed' } } }, + ], + } + expect(restoreReleasedV4Artifact(artifact, new Set(artifact.events.map(event => event.type)))).toBe(artifact) + expect(artifact.events[4]?.data).toMatchObject({ source: { kind: 'compact-checkpoint', compactionId: 'compact-1' } }) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/catalog-completion.spec.ts b/packages/session/session-format-v3-to-v4/tests/catalog-completion.spec.ts new file mode 100644 index 0000000000..7b1ad7e3c0 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/catalog-completion.spec.ts @@ -0,0 +1,178 @@ +import { describe, expect, it } from 'vitest' +import { isSessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { catalogFact, childCatalogFact, childCatalogSubject } from '../src/facts.ts' +import type { SessionFormatEvent, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatV3ToV4, historicalChildCatalogSource, sessionFormatV3ToV4 } from '../src/index.ts' + +const header = { version: 3, id: 'parent', createdAt: 1, isSeeded: false, delegationDepth: 0 } +const child = { version: 0, childId: 'child', childCreatedAt: 2, mode: 'continuable', label: 'child task' } + +function migrate(events: SessionFormatEvent[], facts: readonly SessionFormatJsonValue[], seeded = false, cut?: number, run = false) { + const migration = createSessionFormatV3ToV4(facts.map((value) => { + if (!isSessionFormatJsonObject(value) || !('version' in value)) return value + const fact = catalogFact(value) + return { childId: fact['childId']!, childCreatedAt: fact['childCreatedAt']!, descriptorCount: 1, + descriptor: { version: 3, provider: 'spawn', mode: fact['mode']!, ...(fact['label'] === undefined ? {} : { label: fact['label'] }) } } + })) + const stage = migration.createStage({ + sourceHeader: { ...header, isSeeded: seeded, ...(seeded ? { parentSession: 'ancestor' } : {}) }, targetHeader: { ...header, version: 4, isSeeded: seeded }, + sourceKind: 'decoded', sourceInheritedEventCount: cut ?? (seeded ? undefined : 0), + }) + const output: SessionFormatEvent[] = [] + const context = { emitEvent: (event: SessionFormatEvent) => { output.push(event) }, emitRun: () => { throw new Error('unexpected run') } } + if (run) stage.transformRun({ runType: 'test', firstSeq: 0, eventCount: events.length, *expand() { yield* events } }, context) + else for (const event of events) stage.transformEvent(event, context) + return { cut: stage.finish(context), events: output } +} + +describe('V3 parent catalog completion', () => { + it('interprets V1 descriptors and includes an evidence source path in diagnostics', () => { + expect(childCatalogFact({ + childId: 'child', childCreatedAt: 2, descriptorCount: 1, + descriptor: { version: 1, provider: 'spawn', label: 'legacy child' }, + })).toEqual({ version: 0, childId: 'child', childCreatedAt: 2, mode: 'continuable', label: 'legacy child' }) + expect(childCatalogSubject({ childId: 'child', sourcePath: '/tmp/session.v3.jsonl' })) + .toBe('Session child (raw log: /tmp/session.v3.jsonl)') + }) + + it('appends deterministic child facts without changing source events', () => { + const source = [{ type: 'feedback/record', seq: 0, time: 10, data: { text: 'retained' } }] + const result = migrate(source, [child]) + expect(result.events[0]).toBe(source[0]) + expect(result.events[1]).toEqual({ type: 'subagent/catalog', seq: 1, time: 10, data: child }) + expect(migrate(source, [child])).toEqual(result) + expect(source).toHaveLength(1) + }) + + it('preserves existing facts and adds only missing children', () => { + const source = [{ type: 'subagent/catalog', seq: 0, time: 5, data: child }] + expect(migrate(source, [child, child]).events).toEqual(source) + expect(migrate(source, [child, { ...child, childId: 'second' }]).events).toHaveLength(2) + }) + + it('does not treat inherited catalog membership as owned', () => { + const source = [ + { type: 'subagent/catalog', seq: 0, time: 1, data: child }, + { type: 'session/end-seed', seq: 1, time: 2, data: { inherited: true } }, + ] + const result = migrate(source, [child], true) + expect(result.cut).toBe(1) + expect(result.events[2]).toMatchObject({ type: 'subagent/catalog', seq: 2, data: child }) + }) + + it('validates catalog payloads only after the final inherited seed marker', () => { + const opaque = { type: 'subagent/catalog', seq: 0, time: 1, data: { version: 99 } } + const seed = { type: 'session/end-seed', seq: 1, time: 2, data: { inherited: true } } + const source = [opaque, seed, { ...opaque, seq: 2 }, { ...seed, seq: 3 }] + expect(migrate(source, [child], true).events).toEqual([ + ...source, { type: 'subagent/catalog', seq: 4, time: 2, data: child }, + ]) + expect(() => migrate([...source, { ...opaque, seq: 4 }], [], true)).toThrow('complete version 0') + expect(() => migrate([opaque], [])).toThrow('complete version 0') + }) + + it('requires explicit corpus facts and refuses conflicting identities', () => { + expect(() => sessionFormatV3ToV4.createStage({ sourceHeader: header, targetHeader: { ...header, version: 4 }, + sourceKind: 'decoded', sourceInheritedEventCount: 0 })).toThrow('explicit historical child facts') + expect(() => migrate([], [{ ...child, mode: 'unknown' }])).toThrow('complete version 0') + expect(() => migrate([{ type: 'subagent/catalog', seq: 0, time: 2, data: child }], [{ ...child, childCreatedAt: 3 }])).toThrow('conflicts') + }) + + it('extracts the own descriptor after a fork prefix', () => { + const artifact = { + header: { ...header, id: 'child', createdAt: 2, origin: 'subagent' as const, parentSession: 'parent', isSeeded: true }, + inheritedEventCount: 1, + events: [ + { type: 'subagent/descriptor', seq: 0, time: 1, data: { version: 3, mode: 'one-shot', provider: 'fork' } }, + { type: 'subagent/descriptor', seq: 1, time: 2, data: { version: 3, mode: 'continuable', provider: 'fork', label: 'child task' } }, + ], + } + expect(childCatalogFact(historicalChildCatalogSource(artifact))).toEqual(child) + expect(migrate([], [historicalChildCatalogSource({ ...artifact, inheritedEventCount: 0 })]).events).toEqual([]) + expect(migrate([], [historicalChildCatalogSource({ ...artifact, events: [] })]).events).toEqual([]) + }) + it('orders tied and differently dated children independently of directory enumeration', () => { + const children = [{ ...child, childId: 'z' }, { ...child, childId: 'a' }, { ...child, childId: 'first', childCreatedAt: 1 }] + expect(migrate([], children).events.map(event => event.data)).toEqual([children[2], children[1], children[0]]) + expect(migrate([], children).events[0]?.time).toBe(1) + }) + + it('rejects duplicates, sparse events, and missing or inconsistent seed cuts', () => { + const catalog = { type: 'subagent/catalog', seq: 0, time: 1, data: child } + expect(() => migrate([catalog, { ...catalog, seq: 1 }], [])).toThrow('duplicate') + expect(() => migrate([{ ...catalog, seq: 1 }], [])).toThrow('dense') + expect(() => migrate([], [], true)).toThrow('inherited event count') + expect(() => migrate([], [], false, 1)).toThrow('disagrees') + expect(migrate([catalog], [], false, undefined, true).events).toEqual([catalog]) + }) + + it('refuses target delivery activation and invalid current delivery ownership', () => { + const preceding = { type: 'feedback/record', seq: 0, time: 1, data: { text: 'prior' } } + const delivery = { type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 1, + data: { sessionId: 'other', throughSeq: 0, sessionFormatVersion: 4 } } + expect(() => migrate([preceding, delivery], [])).toThrow('claims target format v4') + expect(() => migrate([preceding, { ...delivery, data: { ...delivery.data, sessionFormatVersion: 3 } }], [])).toThrow('wrong Session') + }) + + it('skips unavailable descriptors while requiring complete discovery fields for new facts', () => { + const artifact = { header: { ...header, origin: 'subagent' as const, parentSession: 'parent' }, inheritedEventCount: 0, events: [] } + expect(() => historicalChildCatalogSource({ ...artifact, header })).toThrow('direct parent') + for (const data of [null, {}, { version: 4, mode: 'one-shot', provider: 'spawn' }]) { + expect(migrate([], [historicalChildCatalogSource({ ...artifact, events: [{ type: 'subagent/descriptor', seq: 0, time: 1, data }] })]).events).toEqual([]) + } + for (const value of [null, { ...child, version: 1 }, { ...child, childId: null }, + { ...child, label: null }, { ...child, childCreatedAt: -1 }]) { + expect(() => migrate([], [value])).toThrow() + } + expect(migrate([], [{ version: 0, childId: 'one-shot', childCreatedAt: 2, mode: 'one-shot' }]).events).toHaveLength(1) + }) + + it.each([null, { version: 99 }])('retains existing catalog extensions without interpreting unavailable descriptors: %j', (descriptor) => { + const data = { ...child, plugin: 'retained' } + const source = [{ type: 'subagent/catalog', seq: 0, time: 1, data }] + expect(migrate(source, [{ childId: 'child', childCreatedAt: 2, descriptorCount: descriptor === null ? 0 : 1, descriptor }]).events).toEqual(source) + }) + + it('keeps parent facts authoritative when a child has multiple own descriptors', () => { + const data = { ...child, extension: { retained: true } } + const source = [{ type: 'subagent/catalog', seq: 0, time: 1, data }] + const evidence = { childId: 'child', childCreatedAt: 2, descriptorCount: 2, + descriptor: { version: 3, mode: 'one-shot', provider: 'spawn', label: 'ambiguous child identity' } } + expect(migrate(source, [evidence]).events).toEqual(source) + expect(() => migrate(source, [{ ...evidence, childCreatedAt: 3 }])).toThrow('conflicts') + }) + + it.each(['missing', 'unknown', 'multiple'] as const)('continues catalog backfill after %s child evidence', (kind) => { + const descriptor: SessionFormatJsonValue = kind === 'missing' ? null : kind === 'unknown' ? { version: 99 } + : { version: 3, mode: 'one-shot', provider: 'spawn' } + const unavailable = { childId: 'unavailable', childCreatedAt: 1, + descriptorCount: kind === 'missing' ? 0 : kind === 'multiple' ? 2 : 1, descriptor } + expect(migrate([], [child, unavailable]).events).toEqual([ + { type: 'subagent/catalog', seq: 0, time: 1, data: child }, + ]) + }) + + it('refuses malformed supplemental evidence and known descriptor conflicts', () => { + for (const source of [null, {}, { childId: 'child', childCreatedAt: 2, descriptor: null, descriptorCount: -1 }]) { + expect(() => migrate([], [source])).toThrow() + } + const source = { childId: 'child', childCreatedAt: 2, descriptorCount: 1, + descriptor: { version: 3, mode: 'continuable', label: 'child task' } } + expect(() => migrate([], [source])).toThrow('invalid subagent descriptor provider') + const existing = [{ type: 'subagent/catalog', seq: 0, time: 1, data: child }] + expect(() => migrate(existing, [{ ...source, descriptor: { ...source.descriptor, provider: 'spawn', label: 'different' } }])).toThrow('conflicts') + }) + + it('validates predecessor delivery before preserving its generation identity', () => { + const prior = { type: 'feedback/record', seq: 0, time: 1, data: { text: 'prior' } } + const marker = { type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 1, + data: { sessionId: 'ancestor', throughSeq: 0, sessionFormatVersion: 3 } } + const seed = { type: 'session/end-seed', seq: 2, time: 2, data: { inherited: true } } + expect(migrate([prior, marker, seed], [], true).events).toEqual([prior, marker, seed]) + expect(() => migrate([prior, { ...seed, seq: 1 }, { ...marker, seq: 2 }], [], true)).toThrow('wrong Session') + expect(migrate([prior, { ...marker, data: { ...marker.data, sessionFormatVersion: 2 } }], []).events).toHaveLength(2) + expect(migrate([prior, { ...marker, data: { ...marker.data, sessionId: 'parent' } }], []).events).toHaveLength(2) + expect(childCatalogFact(historicalChildCatalogSource({ header: { ...header, origin: 'subagent', parentSession: 'ancestor' }, inheritedEventCount: 0, + events: [{ type: 'subagent/descriptor', seq: 0, time: 1, data: { version: 3, mode: 'one-shot', provider: 'spawn' } }] }))).toEqual({ version: 0, childId: 'parent', childCreatedAt: 1, mode: 'one-shot' }) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/codec.spec.ts b/packages/session/session-format-v3-to-v4/tests/codec.spec.ts new file mode 100644 index 0000000000..7a3f8cac20 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/codec.spec.ts @@ -0,0 +1,162 @@ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { releasedV2SessionFormatCodec } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { assertReleasedV4Header, assertV4RowAdmission, releasedV4SessionFormatCodec, restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { version: 4, id: 'parent', createdAt: 1, isSeeded: false, delegationDepth: 0 } +const fact: SessionFormatEvent = { type: 'feedback/record', seq: 0, time: 1, data: { text: 'retained' } } +const catalog: SessionFormatEvent = { type: 'subagent/catalog', seq: 0, time: 1, data: { version: 0, childId: 'child', childCreatedAt: 2, mode: 'one-shot' } } +const types = new Set(['subagent/catalog', 'feedback/record', 'session-log-deepseek/delivery-accepted', 'session/end-seed']) +const delivery = (version: number | undefined, sessionId = header.id): SessionFormatEvent => ({ + type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 2, + data: { sessionId, throughSeq: 0, ...(version === undefined ? {} : { sessionFormatVersion: version }) }, +}) + +function restore(events: readonly SessionFormatEvent[], sourceHeader = header) { + return restoreReleasedV4Artifact({ header: sourceHeader, events, inheritedEventCount: 0 }, types) +} + +describe('V4 framing and restoration', () => { + it('reuses released V2 physical framing and round trips native V4 rows', () => { + const physical = releasedV4SessionFormatCodec.encodeHeader(header, 0) + expect(physical).toEqual({ type: 'session', ...header }) + expect(releasedV4SessionFormatCodec.decodeHeader(physical)).toEqual(header) + const decoder = releasedV4SessionFormatCodec.createDecoder(physical, 'strict') + const output = new SessionFormatEventCollector() + expect(decoder.header).toEqual(header) + const row = releasedV4SessionFormatCodec.encodeEvent(fact) + expect(row).toEqual(releasedV2SessionFormatCodec.encodeEvent(fact)) + decoder.decodeRow(row, output) + expect(decoder.finish(output)).toBe(0) + expect(output.values).toEqual([fact]) + const artifact = { header, events: output.values, inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, types)).toBe(artifact) + }) + + it('rejects mismatched versions and malformed logical and physical metadata', () => { + expect(() => { assertReleasedV4Header({ ...header, version: 3 }) }).toThrow('v4 header') + expect(() => { assertReleasedV4Header({ ...header, createdAt: -1 }) }).toThrow('createdAt') + expect(() => releasedV4SessionFormatCodec.decodeHeader(null)).toThrow('v4 physical') + expect(() => releasedV4SessionFormatCodec.createDecoder({ ...header, version: 3 }, 'strict')).toThrow('v4 physical') + expect(() => releasedV4SessionFormatCodec.decodeHeader({ type: 'session', ...header, extra: 1 })).toThrow(/field|member/) + }) + + it('rejects malformed optional and required native header fields', () => { + const { id: _id, ...missingId } = header + const malformed = [ + [missingId, 'lacks required field id'], + [{ ...header, extra: true }, 'unexpected field extra'], + [{ ...header, id: 7 }, 'id must be a string'], + [{ ...header, isSeeded: 'no' }, 'isSeeded must be boolean'], + [{ ...header, cwd: 'relative' }, 'cwd must be absolute'], + [{ ...header, cwd: 7 }, 'cwd must be absolute'], + [{ ...header, parentSession: 7 }, 'parentSession must be a string'], + [{ ...header, agentPreset: 7 }, 'agentPreset must be a string'], + [{ ...header, origin: 'parent' }, 'origin must be "subagent"'], + ] as const + for (const [value, message] of malformed) { + expect(() => { assertReleasedV4Header(value) }).toThrow(message) + } + }) + + it('rejects released wrapper rows before structural recovery can admit them', () => { + const wrapperRow: SessionFormatEvent = { + type: 'tool/result', seq: 0, time: 1, data: { message: { role: 'user' } }, + } + expect(() => { assertV4RowAdmission(wrapperRow) }).toThrow(/first-class message/) + }) + + it('retains predecessor and future delivery generations without activating their watermarks', () => { + for (const version of [undefined, 0, 1, 2, 3, 5]) { + const marker = { ...delivery(version, 'foreign'), data: { ...delivery(version).data as SessionFormatJsonObject, sessionId: 'foreign', throughSeq: 500 } } + expect(restore([fact, marker]).events[1]).toBe(marker) + } + const current = delivery(4) + expect(restore([fact, current]).events[1]).toBe(current) + expect(() => restore([fact, delivery(4, 'foreign')])).toThrow('wrong Session') + }) + + it('rejects malformed active delivery coordinates and malformed generation identifiers', () => { + const marker = delivery(4) + const data = marker.data as SessionFormatJsonObject + for (const throughSeq of [-1, 1, 1.5]) { + expect(() => restore([fact, { ...marker, data: { ...data, throughSeq } }])).toThrow('throughSeq') + } + for (const sessionId of ['', null, 3]) { + expect(() => restore([fact, { ...marker, data: { ...data, sessionId } }])).toThrow('nonempty') + } + for (const sessionFormatVersion of [-1, -0, 1.5, '4', null]) { + expect(() => restore([fact, { ...marker, data: { ...data, sessionFormatVersion } }])).toThrow('sessionFormatVersion') + } + expect(() => restore([fact, { ...marker, data: null }])).toThrow('data must be an object') + const reader = sessionFormatCatalog.createRestore({ type: 'session', ...header }, { recovery: 'strict', validation: 'current' }) + reader.decodeRow(fact) + reader.decodeRow({ ...marker, data: { ...data, throughSeq: 1 } }) + expect(() => reader.finish()).toThrow('throughSeq') + }) + + it('preserves inherited and local events and admits foreign active deliveries inside the seed only', () => { + const inherited = delivery(4, 'ancestor') + const artifact = { + header: { ...header, isSeeded: true, parentSession: 'ancestor' }, inheritedEventCount: 2, + events: [fact, inherited, { type: 'session/end-seed', seq: 2, time: 3, data: { inherited: true } }, { ...fact, seq: 3 }], + } + expect(restoreReleasedV4Artifact(artifact, types)).toBe(artifact) + expect(() => restoreReleasedV4Artifact({ ...artifact, inheritedEventCount: 1 }, types)).toThrow('marker') + }) + + it('rejects invalid inherited cuts, sparse rows, and unseeded inherited markers', () => { + expect(() => restoreReleasedV4Artifact({ header, inheritedEventCount: 1, events: [] }, types)) + .toThrow('exceeds its events') + expect(() => restoreReleasedV4Artifact({ header, inheritedEventCount: 1, events: [fact] }, types)) + .toThrow('unseeded format v4 Session has inherited events') + expect(() => restoreReleasedV4Artifact({ header, inheritedEventCount: 0, + events: [{ ...fact, seq: 1 }] }, types)).toThrow('not dense') + expect(() => restoreReleasedV4Artifact({ header, inheritedEventCount: 0, + events: [{ type: 'session/end-seed', seq: 0, time: 1, data: { inherited: true } }] }, types)) + .toThrow('unseeded Session contains an inherited end-seed marker') + }) + + it('preserves unknown ignorable values and requires installed vocabulary for unknown required events', () => { + const opaque = { type: 'external/opaque', seq: 0, time: 1, data: { untouched: ['a', 3] }, ignorable: true } + expect(restore([opaque]).events[0]).toBe(opaque) + const required = { type: 'external/required', seq: 0, time: 1, data: null } + expect(() => restore([required])).toThrow('unknown event type') + const artifact = { header, events: [required], inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, new Set([required.type]))).toBe(artifact) + }) + + it('refuses wrapper-shaped and malformed native tool results before recovery', () => { + const wrapper = { type: 'tool/result', seq: 0, time: 1, data: { message: { id: 'result', role: 'user', source: { kind: 'tool', callId: 'call' }, content: [] } } } + const malformed = { type: 'tool/result', seq: 0, time: 1, data: { message: { id: 'result', role: 'tool', source: { kind: 'tool', callId: 'call' }, toolCallId: 'call', content: [], isError: 'yes' } } } + for (const row of [wrapper, malformed]) { + expect(() => { assertV4RowAdmission(row) }).toThrow() + const decoder = releasedV4SessionFormatCodec.createDecoder({ type: 'session', ...header }, 'recoverable') + const output = new SessionFormatEventCollector() + decoder.decodeRow(null, output) + expect(() => { decoder.decodeRow(row, output) }).toThrow() + } + }) + + it('leaves ordinary framing recovery to the released decoder', () => { + expect(() => { assertV4RowAdmission(null) }).not.toThrow() + expect(() => { assertV4RowAdmission(fact) }).not.toThrow() + const decoder = releasedV4SessionFormatCodec.createDecoder({ type: 'session', ...header }, 'recoverable') + const output = new SessionFormatEventCollector() + decoder.decodeRow(fact, output) + decoder.decodeRow(null, output) + expect(decoder.finish(output)).toBe(0) + expect(output.values).toEqual([fact]) + }) + it('rejects duplicate own catalog membership', () => { + expect(() => restore([catalog, { ...catalog, seq: 1 }])).toThrow('duplicate catalog child') + }) + + it('keeps inherited catalog entries outside own uniqueness checks', () => { + const artifact = { header: { ...header, isSeeded: true, parentSession: 'ancestor' }, inheritedEventCount: 1, + events: [catalog, { type: 'session/end-seed', seq: 1, time: 2, data: { inherited: true } }, { ...catalog, seq: 2 }] } + expect(restoreReleasedV4Artifact(artifact, types)).toBe(artifact) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/content.spec.ts b/packages/session/session-format-v3-to-v4/tests/content.spec.ts new file mode 100644 index 0000000000..2b2b564ce1 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/content.spec.ts @@ -0,0 +1,208 @@ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { migrateV3Content, migrateV3EventContent } from '../src/content.ts' +import { createSessionFormatV3ToV4, releasedV4SessionFormatCodec } from '../src/index.ts' +import { assertV4MessageSources } from '../src/message-sources.ts' +import { namespaceV3OpaqueEvent } from '../src/extension-identities.ts' + +const image = { type: 'image', attachment: { attachmentId: 'image', mediaType: 'image/png', bytes: 1, width: 1, height: 1 } } +const wrapper = { type: 'future', content: [{ type: 'tool-result', toolCallId: 'opaque', content: [image] }] } +const convertedBlock = { ...wrapper, type: 'plugin:future' } +const user = { id: 'user', role: 'user', source: { kind: 'user' }, content: [wrapper] } +const event = (type: string, data: SessionFormatJsonValue): SessionFormatEvent => ({ type, seq: 0, time: 1, data }) + +function migrate(row: SessionFormatEvent): SessionFormatEvent { + const sourceHeader = { version: 3, id: 'content', createdAt: 0, isSeeded: false, delegationDepth: 0 } + const stage = createSessionFormatV3ToV4([]).createStage({ sourceHeader, targetHeader: { ...sourceHeader, version: 4 }, sourceInheritedEventCount: 0, sourceKind: 'decoded' }) + const collector = new SessionFormatEventCollector() + stage.transformEvent(row, collector) + stage.finish(collector) + return collector.values[0]! +} + +describe('V3 content conversion', () => { + it('preserves own extension keys without changing opaque values or source content', () => { + const old = JSON.parse('{"type":"vendor","metadata":{"tag":"old"},"__proto__":{"saved":true},"constructor":{"saved":false}}') as SessionFormatJsonObject + const actual = migrateV3Content([old, image], 'sample') + expect(actual).toEqual([{ ...old, type: 'plugin:vendor' }, image]) + const data = actual[0] as SessionFormatJsonObject + expect(Object.hasOwn(data, '__proto__')).toBe(true) + expect(Object.getPrototypeOf(data)).toBe(Object.prototype) + expect(actual[1]).toBe(image) + expect(old['type']).toBe('vendor') + }) + + it.each(['message', 'extension', 'tool-addition', 'tool-removal', '', 'future', 'plugin:future'])('keeps the unknown V3 tag %j opaque', (type) => { + const block = { type, content: [wrapper], message: { role: 'tool', content: [wrapper] }, data: wrapper } + expect(migrateV3Content([block], 'sample')).toEqual([{ ...block, type: `plugin:${type}` }]) + }) + + it('shares unchanged leaves and ignores JSON that is not a declared content slot', () => { + const content = [{ type: 'text', text: 'saved', metadata: wrapper }, { type: 'tool-call', id: 'call', name: 'echo', arguments: JSON.stringify(wrapper) }, image] + expect(migrateV3Content(content, 'sample')).toBe(content) + const row = event('user/message', { ...user, content, replayState: wrapper, schema: { examples: [wrapper] } }) + expect(migrateV3EventContent(row)).toBe(row) + const opaque = event('future', { content: [wrapper] }) + expect(migrateV3EventContent(opaque)).toBe(opaque) + const scalar = event('future', null) + expect(migrateV3EventContent(scalar)).toBe(scalar) + }) + + it.each([ + ['user/message', user, { ...user, content: [convertedBlock] }], + ['system/message', { message: user }, { message: { ...user, content: [convertedBlock] } }], + ['assistant/message', { message: user }, { message: { ...user, content: [convertedBlock] } }], + ['agent/inbox/spliced', { inserted: [user] }, { inserted: [{ ...user, content: [convertedBlock] }] }], + ['session/title-llm-request', { messages: [user] }, { messages: [{ ...user, content: [convertedBlock] }] }], + ['compaction/summary', { summary: [wrapper], rawOutput: [wrapper] }, { summary: [convertedBlock], rawOutput: [convertedBlock] }], + ['compaction/summary', { summary: [] }, { summary: [] }], + ['tool/ptc-dispatch', { content: [wrapper] }, { content: [convertedBlock] }], + ['team/message/queued', { message: user }, { message: { ...user, content: [convertedBlock] } }], + ['team/message/queued', { message: { ...user, content: [] } }, { message: { ...user, content: [] } }], + ['team/message/queued', { message: null }, { message: null }], + ] as const)('converts declared %s content without changing envelope coordinates', (type, data, expected) => { + const row = { + ...event(type, data), seq: 3, sourceEventSeqs: [0, 2], surfaceOp: { op: 'replace', startSeq: 0, endSeq: 2 }, extra: { content: [wrapper] }, + } as SessionFormatEvent + const before = structuredClone(row) + expect(migrateV3EventContent(row)).toEqual({ ...row, data: expected }) + expect(row).toEqual(before) + }) + + it.each(['assistant/message', 'assistant/attempt'])('converts raw %s start/end blocks and preserves start-owned fields', (type) => { + const chunk = (value: SessionFormatJsonValue): SessionFormatJsonObject => ({ type: 'chunk', chunk: value, time: 7 }) + const stream = [ + chunk({ type: 'block-start', index: 0, blockType: 'future', extensionName: 'old', metadata: { old: true }, custom: wrapper }), + chunk({ type: 'block-end', index: 0, block: wrapper }), + chunk({ type: 'block-start', index: 1, blockType: 'message' }), + chunk({ type: 'block-end', index: 1, block: { type: 'message', content: [wrapper] } }), + chunk({ type: 'block-start', index: 2, blockType: 'text' }), + chunk({ type: 'block-start', index: 3, blockType: 'text', metadata: { original: true } }), + chunk({ type: 'block-end', index: 2, block: { type: 'text', text: 'after' } }), + chunk({ type: 'text-delta', index: 2, text: 'after' }), + chunk(null), null, { type: 'annotation', data: wrapper }, + ] + const actual = migrateV3EventContent(event(type, { message: { ...user, content: [] }, stream })) + expect(actual.data).toEqual({ message: { ...user, content: [] }, stream: [ + chunk({ type: 'block-start', index: 0, blockType: 'plugin:future', extensionName: 'old', metadata: { old: true }, custom: wrapper }), + chunk({ type: 'block-end', index: 0, block: convertedBlock }), + chunk({ type: 'block-start', index: 1, blockType: 'plugin:message' }), + chunk({ type: 'block-end', index: 1, block: { type: 'plugin:message', content: [wrapper] } }), + stream[4], stream[5], + ...stream.slice(6), + ] }) + const unchanged = event(type, { message: { ...user, content: [] }, stream: stream.slice(6) }) + expect(migrateV3EventContent(unchanged)).toBe(unchanged) + }) + + it('preserves V3 request-tool metadata keys and values', () => { + const parameters = { type: 'object', properties: {}, examples: [wrapper], deferLoading: true } + const extras = JSON.parse('{"vendor":{"saved":true},"plugin:vendor":{"saved":false},"plugin:deferLoading":false,"__proto__":{"saved":"prototype"},"constructor":{"saved":"constructor"}}') as SessionFormatJsonObject + const tool = { name: 'echo', description: 'Echo', parameters, ...extras } + const row = event('request/header', { reason: 'initial', header: { config: { provider: 'mock', model: 'mock' }, tools: [tool] } }) + const before = structuredClone(row) + const converted = migrate(row) + expect(converted).toBe(row) + expect(converted).toEqual(before) + expect(() => releasedV4SessionFormatCodec.encodeEvent(converted)).not.toThrow() + expect(Object.hasOwn(tool, '__proto__')).toBe(true) + expect(Object.getPrototypeOf(tool)).toBe(Object.prototype) + expect(tool.parameters.deferLoading).toBe(true) + expect(tool).toHaveProperty('plugin:deferLoading', false) + }) + + it.each([true, false, null, 'custom'])('refuses an unsupported V3 top-level deferLoading value %j without altering the source', (deferLoading) => { + const tool = { name: 'echo', description: 'Echo', parameters: {}, deferLoading } + const row = event('request/header', { reason: 'initial', header: { + config: { provider: 'mock', model: 'mock' }, + tools: [{ name: 'first', description: 'First', parameters: {} }, tool], + } }) + const before = structuredClone(row) + expect(() => migrate(row)).toThrow(/request\/header at seq 0.*tools\[1\].*deferLoading/) + expect(row).toEqual(before) + }) + + it('preserves stream-start extra keys while converting its unknown block type', () => { + const extra = JSON.parse('{"deferLoading":true,"plugin:deferLoading":false,"metadata":{"saved":1},"plugin:metadata":{"saved":2},"__proto__":{"saved":3}}') as SessionFormatJsonObject + const start = { type: 'block-start', index: 7, blockType: 'plugin:text', ...extra } + const stream = migrateV3EventContent(event('assistant/attempt', { stream: [{ type: 'chunk', chunk: start }] })) + expect(stream.data).toEqual({ stream: [{ type: 'chunk', chunk: { ...start, blockType: 'plugin:plugin:text' } }] }) + expect(extra['deferLoading']).toBe(true) + expect(Object.hasOwn(extra, '__proto__')).toBe(true) + }) + + it('retains native V4 deferred-loading declaration validation', () => { + const tool = { name: 'echo', description: 'Echo', parameters: {}, deferLoading: true } + const header = { config: { provider: 'mock', model: 'mock' }, tools: [tool] } + const row = event('request/header', { header }) + const physical = releasedV4SessionFormatCodec.encodeEvent(row) + const collector = new SessionFormatEventCollector() + releasedV4SessionFormatCodec.createDecoder({ type: 'session', version: 4, id: 'native', createdAt: 0, isSeeded: false, delegationDepth: 0 }, 'strict').decodeRow(physical, collector) + expect(collector.values).toEqual([row]) + expect(() => releasedV4SessionFormatCodec.encodeEvent(event('request/header', { + header: { ...header, tools: [{ ...tool, deferLoading: false }] }, + }))).toThrow(/deferLoading must be true/) + }) + + it('shares V3 request tools with no extension fields and leaves malformed tools decoder-owned', () => { + for (const header of [null, {}, { tools: null }, { tools: [{ name: 'echo', description: 'Echo', parameters: {} }, null] }]) { + const row = event('request/header', { header }) + expect(migrateV3EventContent(row)).toBe(row) + } + }) + + it('leaves missing message sources for native admission to reject', () => { + const row = event('user/message', { id: 'missing-source', role: 'user', content: [] }) + const converted = migrate(row) + expect(converted).toBe(row) + expect(() => { assertV4MessageSources(converted) }).toThrow(/producer-owned source kind/) + }) + + it('rejects non-array content at the durable conversion boundary', () => { + expect(() => migrateV3Content({}, 'sample')).toThrow(/content must be an array/) + }) + + it.each([null, {}, { type: 4 }])('rejects type-invalid content %j', (block) => { + expect(() => migrateV3Content([block], 'sample')).toThrow(/string type tags/) + }) + + it('rejects a stream start without a string blockType', () => { + expect(() => migrateV3EventContent(event('assistant/attempt', { stream: [{ type: 'chunk', chunk: { type: 'block-start', index: 0 } }] }))).toThrow(/blockType must be a string/) + }) +}) + +describe('native V4 opaque content', () => { + it.each(['system', 'user'])('round trips %s extension content', (role) => { + const message = { ...user, role, source: { kind: role === 'system' ? 'system-prompt' : 'user' }, content: [convertedBlock, { type: 'plugin:future', content: [wrapper] }] } + const row = event(`${role}/message`, role === 'user' ? message : { turn: 1, step: 1, message }) + const physical = releasedV4SessionFormatCodec.encodeEvent(row) + const collector = new SessionFormatEventCollector() + releasedV4SessionFormatCodec.createDecoder({ type: 'session', version: 4, id: 'native', createdAt: 0, isSeeded: false, delegationDepth: 0 }, 'strict').decodeRow(physical, collector) + expect(collector.values).toEqual([row]) + }) +}) + +describe('unknown V3 event identities', () => { + it.each(['developer/message', 'plugin:developer/message', 'future', '\ud800'])('namespaces %j while retaining opaque data and envelope fields', (type) => { + const row = { ...event(type, { message: user, content: [wrapper] }), ignorable: true, sourceEventSeqs: [0], surfaceOp: 'append', extra: { saved: true } } as SessionFormatEvent + const expected = { ...row, type: `plugin:${type}` } + expect(migrate(row)).toEqual(expected) + expect(expected.data).toBe(row.data) + expect(namespaceV3OpaqueEvent(expected).type).not.toBe(expected.type) + }) + + it('leaves incomplete delivery payloads for generation validation', () => { + for (const data of [null, {}, { sessionFormatVersion: '4' }]) { + const row = event('session-log-deepseek/delivery-accepted', data) + expect(namespaceV3OpaqueEvent(row)).toBe(row) + } + }) + + it('leaves required unknown event identities for the migration stage to reject', () => { + const unknown = event('future', {}) + expect(namespaceV3OpaqueEvent(unknown)).toBe(unknown) + const known = event('turn/start', { turn: 1 }) + expect(namespaceV3OpaqueEvent(known)).toBe(known) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/corpus.spec.ts b/packages/session/session-format-v3-to-v4/tests/corpus.spec.ts new file mode 100644 index 0000000000..e13675fd0f --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/corpus.spec.ts @@ -0,0 +1,118 @@ +import { readFileSync, readdirSync } from 'node:fs' +import { join, resolve } from 'node:path' +import { expect, it } from 'vitest' +import { createSessionFormatCatalogWithChildren, historicalSessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { isSessionFormatJsonObject, type SessionFormatArtifact, type SessionFormatEvent, type SessionFormatJsonObject, type SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { historicalChildCatalogSource } from '../src/index.ts' +import { mapEventMessages, rewritePluginSource } from '../src/sources.ts' +import { liftToolResult } from '../src/tool-role.ts' + +const root = resolve(import.meta.dirname, '../../../..') + +function restoreFixture(path: string): SessionFormatArtifact { + const records = readFileSync(join(root, path), 'utf8').trim().split('\n').map(line => JSON.parse(line) as Record) + const header = records.shift()! + if (typeof header['cwd'] === 'string' && header['cwd'].startsWith('{{cwd}}')) header['cwd'] = resolve('snapshot-cwd') + const restore = historicalSessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const [seq, record] of records.entries()) { + if (record['type'] === 'request/header' && isSessionFormatJsonObject(record['data']) && isSessionFormatJsonObject(record['data']['header'])) { + const request = { ...record['data']['header'] } + record['data'] = { ...record['data'], header: request } + if (request['tools'] === '{{tools}}') delete request['tools'] + else if (Array.isArray(request['tools']) && request['tools'].every(tool => typeof tool === 'string')) { + request['tools'] = request['tools'].map(name => ({ name, description: '', parameters: {} })) + } + } + restore.decodeRow({ ...record, seq: record['seq'] ?? seq, time: record['time'] ?? 0 }) + } + return restore.finish() +} + +function migrate(parent: SessionFormatArtifact, children: SessionFormatArtifact[]) { + const restore = createSessionFormatCatalogWithChildren(children.map(historicalChildCatalogSource)).createRestore({ type: 'session', ...parent.header }, { + recovery: 'strict', validation: 'current', + }) + for (const event of parent.events) restore.decodeRow(event) + return restore.finish() +} + +function migrateEvent(event: SessionFormatEvent): SessionFormatEvent { + const rewritten = mapEventMessages(event, (message) => { + const source = message['source'] + if (!isSessionFormatJsonObject(source) || source['kind'] !== 'plugin') return message + return { ...message, source: rewritePluginSource(source, event.seq, message['role']) } + }) + return liftToolResult(rewritten) +} + +it('refuses recorded parent/child clock conflicts and migrates consistent copies including failed startup', () => { + const conflicts: string[] = [] + let pairs = 0 + let withoutDescriptor = 0 + for (const profile of ['sdk', 'session']) { + const base = `snapshots/${profile}` + for (const dir of readdirSync(join(root, base), { withFileTypes: true })) { + if (!dir.isDirectory()) continue + const names = readdirSync(join(root, base, dir.name)).filter(name => /^session(?:\.\d+)?\.v3\.jsonl$/.test(name)) + if (names.length < 2) continue + const logs = names.map(name => ({ path: `${base}/${dir.name}/${name}`, artifact: restoreFixture(`${base}/${dir.name}/${name}`) })) + for (const parent of logs) { + const children = logs.filter(child => child.artifact.header.origin === 'subagent' && child.artifact.header.parentSession === parent.artifact.header.id) + if (children.length === 0) continue + pairs += children.length + const catalogs = parent.artifact.events.filter(event => event.type === 'subagent/catalog' && event.seq >= parent.artifact.inheritedEventCount) + const aligned = children.map((child) => { + const catalog = catalogs.find(event => isSessionFormatJsonObject(event.data) && event.data['childId'] === child.artifact.header.id)?.data + expect(isSessionFormatJsonObject(catalog), child.path).toBe(true) + const createdAt = (catalog as SessionFormatJsonObject)['childCreatedAt'] as number + if (createdAt !== child.artifact.header.createdAt) conflicts.push(child.path) + if (historicalChildCatalogSource(child.artifact)['descriptorCount'] === 0) withoutDescriptor++ + // Only this detached control changes a clock; committed generations are immutable rejection evidence. + return { ...child.artifact, header: { ...child.artifact.header, createdAt } } + }) + if (children.some(child => conflicts.includes(child.path))) { + expect(() => migrate(parent.artifact, children.map(child => child.artifact)), parent.path).toThrow('conflicts with its parent catalog') + } else { + expect(migrate(parent.artifact, children.map(child => child.artifact)).events, parent.path).toEqual( + parent.artifact.events.map(migrateEvent), + ) + } + expect(migrate(parent.artifact, aligned), parent.path).toEqual({ + ...parent.artifact, + header: { ...parent.artifact.header, version: 4 }, + events: parent.artifact.events.map(migrateEvent), + }) + } + } + } + expect(pairs).toBe(25) + expect(withoutDescriptor).toBe(1) + expect(conflicts.sort()).toEqual(EXPECTED_CONFLICTS) +}) + +const EXPECTED_CONFLICTS = [ + 'snapshots/sdk/subagent-continuable-inheritance/session.1.v3.jsonl', + 'snapshots/sdk/subagent-continuable/session.1.v3.jsonl', + 'snapshots/sdk/subagent-fork-in-process/session.1.v3.jsonl', + 'snapshots/sdk/subagent-list-agents/session.1.v3.jsonl', + 'snapshots/sdk/subagent-mixed/session.1.v3.jsonl', + 'snapshots/sdk/subagent-mixed/session.2.v3.jsonl', + 'snapshots/sdk/subagent-send-message/session.1.v3.jsonl', + 'snapshots/sdk/subagent-spawn-in-process/session.1.v3.jsonl', + 'snapshots/session/advanced-toolchain-runtime/session.1.v3.jsonl', + 'snapshots/session/advanced-toolchain-runtime/session.2.v3.jsonl', + 'snapshots/session/advanced-toolchain/session.1.v3.jsonl', + 'snapshots/session/advanced-toolchain/session.2.v3.jsonl', + 'snapshots/session/ralph-loop/session.1.v3.jsonl', + 'snapshots/session/ralph-loop/session.2.v3.jsonl', + 'snapshots/session/subagent-child-question-rejection/session.1.v3.jsonl', + 'snapshots/session/subagent-depth-two-rejection/session.1.v3.jsonl', + 'snapshots/session/subagent-depth-two-rejection/session.2.v3.jsonl', + 'snapshots/session/subagent-max-tokens-partial/session.1.v3.jsonl', + 'snapshots/session/subagent-parallel/session.1.v3.jsonl', + 'snapshots/session/subagent-parallel/session.2.v3.jsonl', + 'snapshots/session/subagent-published-run-failure/session.1.v3.jsonl', + 'snapshots/session/subagent-spawn-in-process/session.1.v3.jsonl', + 'snapshots/session/subagent-tool-filter/session.1.v3.jsonl', + 'snapshots/session/workflow-run/session.1.v3.jsonl', +] diff --git a/packages/session/session-format-v3-to-v4/tests/developer-relationships.spec.ts b/packages/session/session-format-v3-to-v4/tests/developer-relationships.spec.ts new file mode 100644 index 0000000000..885784bc8c --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/developer-relationships.spec.ts @@ -0,0 +1,112 @@ +/** Developer surface positions and admission remain distinct from unknown ignorable records. */ +import { describe, expect, it } from 'vitest' +import { Session, SessionId, SessionLogOffset } from '@deepseek-ai/dsh-session' +import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatArtifact, SessionFormatEvent, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { assertV4RowAdmission, releasedV4SessionFormatCodec as codec, restoreReleasedV4Artifact } from '../src/index.ts' + +type Row = { + type: string + data: SessionFormatJsonValue + surfaceOp?: SessionFormatJsonValue + sourceEventSeqs?: SessionFormatJsonValue + ignorable?: true +} +const coordinates = { turn: 1, step: 1 } +const begin: Row[] = [ + { type: 'turn/start', data: { turn: 1 } }, + { type: 'step/start', data: coordinates }, +] +const system: Row = { type: 'system/message', surfaceOp: 'append', data: { + ...coordinates, message: { id: 'system', role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'text', text: 'System' }] }, +} } +const emptyDeveloper: Row = { type: 'developer/message', surfaceOp: 'append', data: { + ...coordinates, message: { id: 'developer', role: 'developer', source: { kind: 'tool-registry' }, content: [] }, +} } + +function artifact(rows: readonly Row[]): SessionFormatArtifact { + return { + header: { version: 4, id: 'developer-relations', createdAt: 1, isSeeded: false, delegationDepth: 0 }, + events: rows.map((row, seq): SessionFormatEvent => ({ ...row, seq, time: seq + 1 })), + inheritedEventCount: 0, + } +} + +function restore(rows: readonly Row[]): SessionFormatArtifact { + const input = artifact(rows) + return restoreReleasedV4Artifact(input, new Set(input.events.map(event => event.type))) +} + +describe('V4 developer relationship admission', () => { + it('retains an empty developer position while replacing the protected system head', () => { + const replacement: Row = { ...system, surfaceOp: { op: 'replace', startSeq: 2, endSeq: 2 }, sourceEventSeqs: [2], data: { + ...coordinates, message: { id: 'replacement', role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'text', text: 'Updated' }] }, + } } + const input = restore([...begin, system, emptyDeveloper, replacement]) + const session = Session.fromRestore(SessionId(input.header.id), input.events as SessionEvent[], + input.header as unknown as SessionHeader, SessionLogOffset(0), 'detached') + expect(session.surface.nodes).toEqual([4, 3]) + expect(session.deriveMessages().map(message => message.id)).toEqual(['replacement']) + expect(input.events[3]?.data).toEqual(emptyDeveloper.data) + }) + + it('rejects an empty developer replacement of the protected system head', () => { + const replacement = { ...emptyDeveloper, surfaceOp: { op: 'replace', startSeq: 2, endSeq: 2 }, sourceEventSeqs: [2] } + expect(() => restore([...begin, system, replacement])).toThrow(/protected system head/) + }) + + it('includes empty developer nodes in compaction spans and protects the system head', () => { + const prune: Row = { type: 'compaction/prune', data: { + shadowedRange: { start: 3, end: 3 }, shadowedSeqs: [3], shadowedTokenCount: 0, + } } + expect(() => restore([...begin, system, emptyDeveloper, prune])).not.toThrow() + expect(() => restore([...begin, system, emptyDeveloper, { ...prune, data: { + shadowedRange: { start: 2, end: 3 }, shadowedSeqs: [2, 3], shadowedTokenCount: 0, + } }])).toThrow(/protected system head/) + }) + + it.each([ + { rows: [begin[0]!, emptyDeveloper] }, + { rows: [...begin, { ...emptyDeveloper, data: { ...coordinates, step: 2, message: { + id: 'developer', role: 'developer', source: { kind: 'tool-registry' }, content: [], + } } }] }, + ])('requires known developer messages to match the current open step %#', ({ rows }) => { + expect(() => restore(rows)).toThrow(/open.*step/) + }) + + + it('defers ignorable developer payloads during physical decoding while keeping encoder validation', () => { + const opaque: Row = { type: 'developer/message', ignorable: true, data: { + message: { role: 'developer', source: { kind: 'plugin' } }, future: true, + }, surfaceOp: { future: true } } + const input = artifact([opaque, ...begin, system]) + const physicalHeader = codec.encodeHeader(input.header, 0) + const decoded = new SessionFormatEventCollector() + const decoder = codec.createDecoder(physicalHeader, 'strict') + for (const event of input.events) decoder.decodeRow(event, decoded) + decoder.finish(decoded) + expect(decoded.values).toEqual(input.events) + expect(() => codec.encodeEvent(input.events[0]!)).toThrow() + expect(() => { assertV4RowAdmission(input.events[0], new Set()) }).not.toThrow() + expect(() => { assertV4RowAdmission(input.events[0], new Set(['developer/message'])) }).toThrow() + + const known = { ...input.events[0]!, data: emptyDeveloper.data } + expect(codec.encodeEvent(known)).toMatchObject({ type: 'developer/message', ignorable: true }) + }) + + it('keeps unknown ignorable developer fields and coordinates opaque before an ordinary step', () => { + const opaque: Row = { type: 'developer/message', ignorable: true, data: { + message: { role: 'developer', source: { kind: 'plugin' } }, future: true, + }, surfaceOp: { future: true }, sourceEventSeqs: { future: true } } + const input = artifact([opaque, ...begin, system]) + const before = JSON.stringify(input) + const known = new Set(input.events.map(event => event.type)) + known.delete('developer/message') + expect(restoreReleasedV4Artifact(input, known)).toBe(input) + expect(JSON.stringify(input)).toBe(before) + expect(input.events.map(event => event.seq)).toEqual([0, 1, 2, 3]) + known.add('developer/message') + expect(() => restoreReleasedV4Artifact(input, known)).toThrow() + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/developer.spec.ts b/packages/session/session-format-v3-to-v4/tests/developer.spec.ts new file mode 100644 index 0000000000..e7ff68f4ce --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/developer.spec.ts @@ -0,0 +1,302 @@ +/** Developer messages and deferred schemas survive native V4 persistence. */ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { assertV4RowAdmission, releasedV4SessionFormatCodec as codec, restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { version: 4, id: 'developer', createdAt: 1, isSeeded: false, delegationDepth: 0 } +const message = { id: 'developer-1', role: 'developer', source: { kind: 'tool-registry' }, content: [{ type: 'tool-addition', toolName: 'search' }, { type: 'tool-removal', toolName: 'old' }] } +const developer: SessionFormatEvent = { type: 'developer/message', seq: 3, time: 4, surfaceOp: 'append', data: { turn: 1, step: 1, headerSeq: 2, message } } +const request: SessionFormatEvent = { type: 'request/header', seq: 2, time: 3, data: { + reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [{ name: 'search', description: 'Search', parameters: {}, deferLoading: true }] }, +} } +function events(): SessionFormatEvent[] { + return [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'step/start', seq: 1, time: 2, data: { turn: 1, step: 1 } }, + request, developer, + { type: 'step/end', seq: 4, time: 5, data: { turn: 1, step: 1 } }, + { type: 'turn/end', seq: 5, time: 6, data: { turn: 1, reason: { kind: 'completed' } } }, + ] +} +function roundTrip(input: SessionFormatEvent[]): SessionFormatEvent[] { + const decoder = codec.createDecoder(codec.encodeHeader(header, 0), 'strict') + const output = new SessionFormatEventCollector() + for (const event of input) decoder.decodeRow(codec.encodeEvent(event), output) + decoder.finish(output) + return output.values +} + +describe('V4 developer messages', () => { + it('round trips native messages and deferred schemas without rewriting native payloads', () => { + const input = events() + expect(roundTrip(input)).toEqual(input) + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, new Set(input.map(event => event.type)))).toBe(artifact) + }) + + it('preserves additional JSON fields in developer data, messages, sources, and blocks', () => { + const input = events() + input[3] = { ...developer, data: { turn: 1, step: 1, headerSeq: 2, metadata: { future: true }, message: { + ...message, metadata: ['retained'], source: { kind: 'tool-registry', future: 1 }, content: [ + { type: 'tool-addition', toolName: 'search', future: true }, + { type: 'tool-removal', toolName: 'old', future: true }, + ], + } } } + input[2] = { ...request, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [{ name: 'search', description: 'Search', parameters: {}, deferLoading: true, future: { retained: true } }] } } } + expect(roundTrip(input)).toEqual(input) + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, new Set(input.map(event => event.type)))).toBe(artifact) + }) + + it.each([undefined, null, '', 1])('rejects a malformed addition name %#', (toolName) => { + const row = { ...developer, data: { turn: 1, step: 1, headerSeq: 2, message: { + ...message, content: [{ type: 'tool-addition', ...(toolName === undefined ? {} : { toolName }) }], + } } } + expect(() => codec.encodeEvent(row)).toThrow('nonempty toolName') + expect(() => { assertV4RowAdmission(row) }).toThrow('nonempty toolName') + }) + + it('refuses an inline definition even when a header and name are present', () => { + const row = { ...developer, data: { turn: 1, step: 1, headerSeq: 2, message: { + ...message, content: [{ type: 'tool-addition', toolName: 'search', tool: { name: 'search', description: 'Duplicate', parameters: {} } }], + } } } + expect(() => codec.encodeEvent(row)).toThrow('omit inline tool definitions') + expect(() => { assertV4RowAdmission(row) }).toThrow('omit inline tool definitions') + }) + + it.each([undefined, null, -1, -0, 1.5, '2'])('rejects an absent or invalid addition header sequence %#', (headerSeq) => { + const row = { ...developer, data: { turn: 1, step: 1, message, ...(headerSeq === undefined ? {} : { headerSeq }) } } + expect(() => codec.encodeEvent(row)).toThrow('headerSeq') + expect(() => { assertV4RowAdmission(row) }).toThrow('headerSeq') + }) + + it('requires removal-only messages to omit the header sequence', () => { + const row = { ...developer, data: { turn: 1, step: 1, headerSeq: 2, message: { + ...message, content: [{ type: 'tool-removal', toolName: 'search' }], + } } } + expect(() => codec.encodeEvent(row)).toThrow('omit headerSeq') + }) + + it.each([0, 3, 50])('refuses a non-header or non-earlier schema reference %s', (headerSeq) => { + const input = events() + input[3] = { ...developer, data: { turn: 1, step: 1, headerSeq, message } } + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, new Set(input.map(event => event.type)))) + .toThrow(/headerSeq.*earlier/) + }) + + it.each([ + { tools: undefined }, + { tools: [null] }, + { tools: [{ name: 'different', description: '', parameters: {} }] }, + { tools: [{ name: 'search', description: 'First', parameters: {} }, { name: 'search', description: 'Second', parameters: {} }] }, + ])('refuses missing or ambiguous names in the referenced header %#', ({ tools }) => { + const input = events() + input[2] = { ...request, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, ...(tools === undefined ? {} : { tools }) } } } + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, new Set(input.map(event => event.type)))) + .toThrow('exactly one tool') + }) + + it.each([ + { name: 'search' }, + { name: 'search', description: null, parameters: {} }, + { name: 'search', description: '', parameters: [] }, + { name: 'search', description: '', parameters: null }, + ])('refuses an incomplete referenced definition %#', (tool) => { + const input = events() + input[2] = { ...request, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [tool] } } } + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, new Set(input.map(event => event.type)))) + .toThrow('complete tool definition') + }) + + it.each([null, request.data])('does not interpret an unknown ignorable header referenced by a known developer event %#', (data) => { + const input = events() + input[2] = { ...request, ignorable: true, data } + const known = new Set(input.map(event => event.type)) + known.delete('request/header') + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, known)).toThrow('known request/header') + input[3] = { ...developer, ignorable: true, data: { opaque: true, headerSeq: { future: true } }, surfaceOp: { future: true } } + known.delete('developer/message') + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, known)).toBe(artifact) + }) + + it('keeps historical schema references when compaction shadows their developer nodes', () => { + const input = [ + ...events().slice(0, 4), + { type: 'compaction/prune', seq: 4, time: 5, data: { shadowedRange: { start: 3, end: 3 }, shadowedSeqs: [3], shadowedTokenCount: 0 } }, + ...events().slice(4).map(event => ({ ...event, seq: event.seq + 1 })), + ] + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, new Set(input.map(event => event.type)))).toBe(artifact) + expect(input[2]).toEqual(request) + }) + + it.each([null, [], 'invalid'])('refuses non-object developer data %j before recovery', (data) => { + const row = { ...developer, data } + expect(() => codec.encodeEvent(row)).toThrow('developer/message data must be an object') + expect(() => { assertV4RowAdmission(row) }).toThrow('developer/message data must be an object') + }) + + it.each([{ turn: 1, step: 1 }, { turn: 1, step: 1, message: null }])( + 'rejects malformed developer event fields %#', (data) => { + expect(() => codec.encodeEvent({ ...developer, data })).toThrow('requires turn, step, and a developer message') + }, + ) + + it('leaves malformed legacy stream chunks to canonical decoding', () => { + expect(() => { assertV4RowAdmission({ type: 'assistant/attempt', seq: 2, time: 3, + data: { stream: [{ type: 'chunk', chunk: null }] }, + }) }).not.toThrow() + }) + + it.each(['agent/inbox/spliced', 'session/title-llm-request'])('leaves malformed ordinary arrays in %s to canonical decoding', (type) => { + const key = type === 'agent/inbox/spliced' ? 'inserted' : 'messages' + expect(() => { assertV4RowAdmission({ type, seq: 2, time: 3, data: { [key]: null } }) }).not.toThrow() + }) + + it.each([false, true])('preserves ordinary tools alongside deferred tools: %s', (mixed) => { + const ordinary = { name: 'ordinary', description: 'Ordinary', parameters: {} } + const tools = mixed ? [ordinary, { ...ordinary, name: 'deferred', deferLoading: true }] : [ordinary] + const input = events() + input[2] = { ...request, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools } } } + expect(roundTrip(input)).toEqual(input) + }) + + it('does not interpret tool entries without deferred markers', () => { + const row = { ...request, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [null] } } } + expect(() => { assertV4RowAdmission(row) }).not.toThrow() + }) + + it('preserves the historical header while replacing a developer surface node', () => { + const replacement = { ...developer, seq: 4, time: 5, surfaceOp: { op: 'replace', startSeq: 3, endSeq: 3 }, sourceEventSeqs: [3], + data: { turn: 1, step: 1, headerSeq: 2, message: { ...message, id: 'developer-2' } } } + const input = [...events().slice(0, 4), replacement, ...events().slice(4).map(event => ({ ...event, seq: event.seq + 1 }))] + expect(roundTrip(input)).toEqual(input) + const restored = restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, new Set(input.map(event => event.type))) + expect(restored.events).toEqual(input) + }) + + it.each([false, null, 'true', 1])('rejects invalid deferred marker %j', (deferLoading) => { + const row = { ...request, data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [{ name: 'search', description: '', parameters: {}, deferLoading }] } } } + expect(() => codec.encodeEvent(row)).toThrow('deferLoading') + expect(() => { assertV4RowAdmission(row) }).toThrow('deferLoading') + }) + + it.each([ + { ...message, role: 'user' }, + { ...message, id: '' }, + { ...message, source: { kind: 'plugin' } }, + { ...message, content: [{ type: 'tool-addition', toolName: '' }] }, + { ...message, content: [{ type: 'tool-removal', toolName: '' }] }, + ])('rejects malformed developer message %#', (invalid) => { + const row = { ...developer, data: { turn: 1, step: 1, message: invalid } } + expect(() => codec.encodeEvent(row)).toThrow() + expect(() => { assertV4RowAdmission(row) }).toThrow() + }) + + it('preserves developer messages inside an inherited prefix', () => { + const inheritedHeader = { ...header, isSeeded: true, parentSession: 'parent' } + const input = events() + const inherited = [ + ...input.slice(0, 4), + { type: 'session/end-seed', seq: 4, time: 5, data: { inherited: true } }, + ...input.slice(4).map(event => ({ ...event, seq: event.seq + 1 })), + ] + const decoder = codec.createDecoder(codec.encodeHeader(inheritedHeader, 4), 'strict') + const output = new SessionFormatEventCollector() + for (const event of inherited) decoder.decodeRow(codec.encodeEvent(event), output) + expect(decoder.finish(output)).toBe(4) + expect(output.values).toEqual(inherited) + const artifact = { header: inheritedHeader, events: output.values, inheritedEventCount: 4 } + expect(restoreReleasedV4Artifact(artifact, new Set(inherited.map(event => event.type)))).toBe(artifact) + }) + + it('refuses developer history when the reader does not know the event type', () => { + const input = events() + const known = new Set(input.map(event => event.type)) + known.delete('developer/message') + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, known)).toThrow('unknown event type') + }) + + it('checks request coordinates and the open step', () => { + const input = events() + input[3] = { ...developer, data: { ...(developer.data as SessionFormatJsonObject), step: 2 } } + const known = new Set(input.map(event => event.type)) + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, known)).toThrow(/open.*step/) + expect(() => codec.encodeEvent({ ...developer, data: { turn: 0, step: 1, message } })).toThrow('positive') + }) + + it.each(['user', 'system', 'assistant', 'tool'])('rejects tool-change blocks in %s messages', (role) => { + for (const type of ['tool-addition', 'tool-removal']) { + const source = role === 'system' ? { kind: 'system-prompt' } + : role === 'assistant' ? { kind: 'model', provider: 'test', model: 'test' } + : role === 'tool' ? { kind: 'tool', callId: 'call' } : { kind: 'user' } + const invalid = { ...message, role, source, content: [{ type, toolName: 'search' }], + ...role === 'tool' ? { toolCallId: 'call', isError: false } : {}, + } + const eventType = role === 'tool' ? 'tool/result' : `${role}/message` + const row = { ...developer, type: eventType, data: role === 'user' ? invalid : { turn: 1, step: 1, message: invalid } } + expect(() => codec.encodeEvent(row)).toThrow('developer role') + expect(() => { assertV4RowAdmission(row) }).toThrow('developer role') + const decoder = codec.createDecoder(codec.encodeHeader(header, 0), 'strict') + expect(() => { decoder.decodeRow(row, new SessionFormatEventCollector()) }).toThrow('developer role') + const input = events() + input[3] = row + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(() => restoreReleasedV4Artifact(artifact, new Set(input.map(event => event.type)))).toThrow('developer role') + } + }) + + it.each(['user/message', 'system/message', 'assistant/message', 'tool/result'])('rejects developer role inside %s before payload recovery', (type) => { + const row = { ...developer, type, data: type === 'user/message' ? message : { turn: 1, step: 1, message } } + expect(() => codec.encodeEvent(row)).toThrow(/must occur together|requires a tool-role message/) + expect(() => { assertV4RowAdmission(row) }).toThrow('must occur together') + const decoder = codec.createDecoder(codec.encodeHeader(header, 0), 'strict') + expect(() => { decoder.decodeRow(row, new SessionFormatEventCollector()) }).toThrow('must occur together') + }) + + it.each(['agent/inbox/spliced', 'session/title-llm-request'])('rejects developer role in %s message arrays', (type) => { + const key = type === 'agent/inbox/spliced' ? 'inserted' : 'messages' + const row = { type, seq: 3, time: 4, data: { [key]: [null, message] } } + expect(() => codec.encodeEvent(row)).toThrow('must occur together') + expect(() => { assertV4RowAdmission(row) }).toThrow('must occur together') + const decoder = codec.createDecoder(codec.encodeHeader(header, 0), 'strict') + expect(() => { decoder.decodeRow(row, new SessionFormatEventCollector()) }).toThrow('must occur together') + const input = events() + input[3] = row + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(() => restoreReleasedV4Artifact(artifact, new Set(input.map(event => event.type)))).toThrow('must occur together') + }) + + it('retains unknown ignorable developer records without interpreting their payload or surface', () => { + const input = events() + input[3] = { ...developer, ignorable: true, data: { future: true }, surfaceOp: { future: true } } + const known = new Set(input.map(event => event.type)) + known.delete('developer/message') + const artifact = { header, events: input, inheritedEventCount: 0 } + expect(restoreReleasedV4Artifact(artifact, known)).toBe(artifact) + }) + + it('still validates known ignorable developer records', () => { + const input = events() + input[3] = { ...developer, ignorable: true, data: { turn: 1, step: 2, headerSeq: 2, message } } + const known = new Set(input.map(event => event.type)) + expect(() => restoreReleasedV4Artifact({ header, events: input, inheritedEventCount: 0 }, known)).toThrow(/open.*step/) + }) + + it.each(['tool-addition', 'tool-removal'])('rejects %s outside developer content, including streamed blocks', (type) => { + const block = { type, toolName: 'search' } + const payloads = [ + { type: 'compaction/summary', data: { summary: [block] } }, + { type: 'compaction/summary', data: { rawOutput: [block] } }, + { type: 'assistant/attempt', data: { stream: [{ type: 'chunk', chunk: { type: 'block-end', block } }] } }, + { type: 'assistant/attempt', data: { stream: [{ type: 'chunk', chunk: { type: 'block-start', blockType: type } }] } }, + { type: 'agent/inbox/spliced', data: { inserted: [{ ...message, role: 'user', content: [block] }] } }, + { type: 'session/title-llm-request', data: { messages: [{ ...message, role: 'user', content: [block] }] } }, + ] + for (const payload of payloads) { + expect(() => { assertV4RowAdmission({ seq: 2, time: 3, ...payload }) }).toThrow('developer role') + } + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/fork.spec.ts b/packages/session/session-format-v3-to-v4/tests/fork.spec.ts new file mode 100644 index 0000000000..a6b8e8298e --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/fork.spec.ts @@ -0,0 +1,154 @@ +import { describe, expect, it } from 'vitest' +import { Context } from '@deepseek-ai/cordis' +import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' +import TokenMeter from '@deepseek-ai/dsh-token-meter' +import ToolResultPruner from '@deepseek-ai/dsh-compaction-tool-result-pruner' +import { SessionFormatEventCollector, type SessionFormatEvent, type SessionFormatArtifact, type SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { Session, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' +import { buildForkSeed } from '@deepseek-ai/dsh-session/fork' +import { createMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import { releasedV4SessionFormatCodec as codec, assertV4RowAdmission, restoreReleasedV4Artifact } from '../src/index.ts' +import { assertV4ForkResult } from '../src/fork-result.ts' + +type MutableResult = { + data: { + message: { id: string; role: 'tool'; toolCallId: string; isError: boolean; content: unknown[] } + error: { name: string } + } + sourceEventSeqs?: number[] +} + +function fork() { + const source = Session.create(SessionId('fork-parent')) + source.append('turn/start', { turn: 1 }) + source.append('step/start', { turn: 1, step: 1 }) + source.append('assistant/message', { + turn: 1, step: 1, stream: [], + message: createMessage({ role: 'assistant', source: { kind: 'model', provider: 'mock', model: 'mock' }, + content: [{ type: 'tool-call', id: ToolCallId('read-one'), name: 'read', arguments: '{}' }] }), + }, { surfaceOp: 'append' }) + const seed = buildForkSeed(source.snapshotEvents(), SessionSeq(2)) + return Session.create(SessionId('fork-child'), seed, { + version: 4, id: SessionId('fork-child'), createdAt: 1, delegationDepth: 0, isSeeded: true, parentSession: source.id, + }, SessionLogOffset(3)) +} + +function artifact(session = fork()): SessionFormatArtifact { + return JSON.parse(JSON.stringify({ + header: session.header, events: session.snapshotEvents(), inheritedEventCount: session.inheritedEventCount, + })) as SessionFormatArtifact +} + +function restore(events: readonly SessionFormatEvent[]) { + return restoreReleasedV4Artifact({ ...artifact(), events }, new Set(events.map(event => event.type))) +} + +describe('V4 fork results', () => { + it('ignores non-object fork-result data and validates non-object sources', () => { + expect(() => { assertV4ForkResult({ type: 'tool/result', data: null }) }).not.toThrow() + expect(() => { assertV4ForkResult({ + type: 'tool/result', seq: 0, surfaceOp: 'append', data: { + error: { code: 'TOOL_NOT_STARTED', name: 'ToolNotStartedError' }, + message: { + id: 'forked-tool-result-undefined-0', role: 'tool', toolCallId: 'call-1', isError: true, + source: null, content: [{ type: 'text', text: 'not started' }], + }, + }, + }) }).toThrow('invalid V4 not-started fork result') + }) + + it('persists original fork IDs and wording, restores relationships and retains nested inherited cuts', () => { + const child = fork() + const original = artifact(child).events + const before = JSON.stringify(original) + const physical = codec.encodeHeader(artifact(child).header, child.inheritedEventCount) + const decoder = codec.createDecoder(physical, 'strict') + const output = new SessionFormatEventCollector() + for (const event of original) { + const row = codec.encodeEvent(event) + expect(() => { assertV4RowAdmission(row) }).not.toThrow() + decoder.decodeRow(row, output) + } + expect(decoder.finish(output)).toBe(3) + expect(output.values).toEqual(original) + expect(restore(output.values).events).toBe(output.values) + expect(JSON.stringify(original)).toBe(before) + const result = child.snapshotEvents().find(event => event.type === 'tool/result')! + expect(result.data.message.id).toBe(`forked-tool-result-read-one-${result.seq}`) + expect(JSON.stringify(result)).toContain('The parent session may have executed it after the fork point.') + const nested = Session.create(SessionId('fork-grandchild'), buildForkSeed(child.snapshotEvents(), result.seq), { + version: 4, id: SessionId('fork-grandchild'), createdAt: 1, delegationDepth: 0, isSeeded: true, parentSession: child.id, + }, SessionLogOffset(result.seq + 1)) + expect(restoreReleasedV4Artifact(artifact(nested), new Set(original.map(event => event.type)))).toBeDefined() + }) + + it('round trips a pruned fork result while preserving its original message identity', async () => { + const ctx = new Context() + try { + new SessionProjectionRegistry(ctx) + new TokenMeter(ctx) + const pruner = new ToolResultPruner(ctx, { thresholdChars: 300, headChars: 100, tailChars: 100 }) + const child = fork() + const original = child.snapshotEvents().find(event => event.type === 'tool/result')! + child.append('turn/start', { turn: 2 }) + child.append('step/start', { turn: 2, step: 1 }) + const pruned = pruner.pruneSession(child) + expect(pruned.pruned).toHaveLength(1) + child.append('step/end', { turn: 2, step: 1 }) + child.append('turn/end', { turn: 2, reason: { kind: 'completed' } }) + const events = artifact(child).events + const replacement = events[pruned.pruned[0]!.replacementSeq]! + expect(replacement.data).toMatchObject({ message: { id: original.data.message.id } }) + expect(replacement.sourceEventSeqs).toEqual([original.seq]) + expect(JSON.stringify(replacement)).toContain('pruned') + const decoder = codec.createDecoder(codec.encodeHeader(artifact(child).header, child.inheritedEventCount), 'strict') + const output = new SessionFormatEventCollector() + for (const event of events) decoder.decodeRow(codec.encodeEvent(event), output) + expect(decoder.finish(output)).toBe(child.inheritedEventCount) + expect(output.values).toEqual(events) + expect(restore(output.values).events).toEqual(events) + const data = replacement.data as SessionFormatJsonObject + const message = data['message'] as SessionFormatJsonObject + const invalid = [ + { ...replacement, sourceEventSeqs: [replacement.seq] }, + { ...replacement, data: { ...data, message: { ...message, id: `forked-tool-result-read-one-${replacement.seq}` } } }, + ] + for (const changed of invalid) { + expect(() => restore(events.map(event => event === replacement ? changed : event))).toThrow() + } + } finally { + await ctx.fiber.dispose() + } + }) + + it('rejects incomplete persisted result fields through V4 restoration', () => { + const original = artifact().events + const result = original.find(event => event.type === 'tool/result')! + const data = result.data as SessionFormatJsonObject + const message = data['message'] as SessionFormatJsonObject + const variants = [ + null, + { ...data, message: { ...message, source: null } }, + ] + for (const invalid of variants) { + const events = original.map(event => event === result ? { ...event, data: invalid } : event) + expect(() => restore(events)).toThrow() + } + }) + + it.each([ + ['ID sequence', (row: MutableResult) => { row.data.message.id = 'forked-tool-result-read-one-0' }], + ['error name', (row: MutableResult) => { row.data.error.name = 'OtherError' }], + ['call ID', (row: MutableResult) => { row.data.message.toolCallId = 'different' }], + ['error result', (row: MutableResult) => { row.data.message.isError = false }], + ['source references', (row: MutableResult) => { row.sourceEventSeqs = [2] }], + ['content', (row: MutableResult) => { row.data.message.content = [] }], + ] as const)('rejects malformed fork %s', (_name, mutate) => { + const events = structuredClone(artifact().events) + const result = events.find(event => event.type === 'tool/result')! + mutate(result as unknown as MutableResult) + expect(() => restore(events)).toThrow() + expect(() => { assertV4RowAdmission(result) }).toThrow() + }) + +}) diff --git a/packages/session/session-format-v3-to-v4/tests/message-sources.spec.ts b/packages/session/session-format-v3-to-v4/tests/message-sources.spec.ts new file mode 100644 index 0000000000..28566a4c3b --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/message-sources.spec.ts @@ -0,0 +1,61 @@ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatCatalogWithChildren, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { assertV4MessageSources, assertV4SourceRowAdmission } from '../src/message-sources.ts' +import { releasedV4SessionFormatCodec } from '../src/codec.ts' + +const header = { type: 'session', version: 4, id: 'sources', createdAt: 1, delegationDepth: 0, isSeeded: false } +function event(source: unknown): SessionFormatEvent { + return { type: 'user/message', seq: 0, time: 1, surfaceOp: 'append', data: { id: 'u', role: 'user', source, content: [{ type: 'text', text: 'hello' }] } } as SessionFormatEvent +} + +function restore(source: unknown, version: 3 | 4 = 4) { + const reader = createSessionFormatCatalogWithChildren([]).createRestore({ ...header, version }, { recovery: 'strict', validation: 'current' }) + reader.decodeRow(JSON.parse(JSON.stringify(event(source)))) + return reader.finish() +} + +describe('V4 source admission', () => { + it.each(['constructor', 'toString', '__proto__'])('migrates external producer %s without interpreting inherited object keys', (plugin) => { + const before = JSON.parse(`{"kind":"plugin","plugin":"${plugin}","__proto__":{"tag":"metadata"},"nested":{"kind":"plugin","plugin":"opaque"}}`) as SessionFormatJsonObject + const expected = JSON.parse(`{"kind":"plugin:${plugin}","__proto__":{"tag":"metadata"},"nested":{"kind":"plugin","plugin":"opaque"}}`) as SessionFormatJsonObject + const migrated = restore(before, 3) + expect(migrated.events[0]?.data).toMatchObject({ source: expected }) + expect(Object.hasOwn((migrated.events[0]?.data as { source: object }).source, '__proto__')).toBe(true) + expect(JSON.stringify(restore(expected))).toBe(JSON.stringify(migrated)) + expect(before['kind']).toBe('plugin') + }) + + it.each(['acme', 'plugin:acme', 'source:acme', '__proto__'])('retains direct source kind %s through migration and native restore', (kind) => { + const source = { kind, extra: { kind: 'plugin', plugin: 'opaque' } } + const migrated = restore(source, 3) + expect(migrated.events[0]?.data).toMatchObject({ source }) + expect(restore(source)).toEqual(migrated) + }) + + it('rejects missing, malformed, empty, and retired source kinds', () => { + for (const source of [null, [], {}, { kind: '' }, { kind: 1 }, { kind: 'plugin', plugin: 'compact' }]) { + expect(() => restore(source)).toThrow(/producer-owned source kind/) + expect(() => { assertV4MessageSources(event(source)) }).toThrow(/producer-owned source kind/) + } + }) + + it('rejects retired wrappers in every declared message slot before recovery can discard them', () => { + const message = event({ kind: 'plugin', plugin: 'compact' }).data + const rows = [event({ kind: 'plugin', plugin: 'compact' }), ...['system/message', 'assistant/message', 'tool/result'].map(type => ({ type, seq: 0, time: 1, data: { message } })), { type: 'agent/inbox/spliced', seq: 0, time: 1, data: { inserted: [message] } }, { type: 'session/title-llm-request', seq: 0, time: 1, data: { messages: [message] } }] + for (const row of rows) { + const decoder = releasedV4SessionFormatCodec.createDecoder(header, 'recoverable') + const output = new SessionFormatEventCollector() + decoder.decodeRow(null, output) + expect(() => { decoder.decodeRow(row, output) }).toThrow(/producer-owned source kind/) + expect(() => sessionFormatCatalog.encodeCurrentEvent(row)).toThrow(/producer-owned source kind/) + } + }) + + it('leaves malformed incomplete rows for normal scanner corruption handling', () => { + for (const row of [null, { type: 'user/message', data: null }, { type: 'system/message', data: {} }, { type: 'agent/inbox/spliced', data: { inserted: false } }, { type: 'agent/inbox/spliced', data: { inserted: [null] } }, { type: 'session/title-llm-request', data: { messages: [event({ kind: 'user' }).data] } }, { type: 'external/event', data: { source: { kind: 'plugin' } } }]) { + expect(() => { assertV4SourceRowAdmission(row) }).not.toThrow() + } + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/migration.spec.ts b/packages/session/session-format-v3-to-v4/tests/migration.spec.ts new file mode 100644 index 0000000000..0c4b64d959 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/migration.spec.ts @@ -0,0 +1,220 @@ +import { describe, expect, it } from 'vitest' +import { restoreReleasedV3Artifact } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatHeader, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatCatalogWithChildren, historicalSessionFormatCatalog, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { releasedV3SessionFormatCodec, createSessionFormatV3ToV4, sessionFormatV3ToV4 } from '../src/index.ts' + +const header: SessionFormatHeader = { version: 3, id: 'identity', createdAt: 1, isSeeded: false, delegationDepth: 0 } +const fact: SessionFormatEvent = { type: 'feedback/record', seq: 0, time: 2, data: { text: 'retained' } } +const seed: SessionFormatEvent = { type: 'session/end-seed', seq: 1, time: 3, data: { inherited: true } } +const delivery = (version: number | undefined, sessionId = header.id): SessionFormatEvent => ({ + type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 3, + data: { sessionId, throughSeq: 0, ...(version === undefined ? {} : { sessionFormatVersion: version }) }, +}) + +function stage(sourceHeader = header, sourceInheritedEventCount?: number) { + return createSessionFormatV3ToV4([]).createStage({ + sourceHeader, targetHeader: sessionFormatV3ToV4.migrateHeader(sourceHeader), + sourceInheritedEventCount, sourceKind: 'decoded', + }) +} + +function migrate(events: readonly SessionFormatEvent[], sourceHeader = header, cut?: number) { + const current = stage(sourceHeader, cut) + const output = new SessionFormatEventCollector() + for (const event of events) current.transformEvent(event, output) + return { events: output.values, cut: current.finish(output) } +} + +function restore(events: readonly SessionFormatEvent[], sourceHeader = header) { + const reader = createSessionFormatCatalogWithChildren([]).createRestore({ type: 'session', ...sourceHeader }, { recovery: 'strict', validation: 'current' }) + for (const event of events) reader.decodeRow(event) + return reader.finish() +} + +function restoreHistorical(events: readonly SessionFormatEvent[], sourceHeader: SessionFormatHeader) { + const reader = historicalSessionFormatCatalog.createRestore({ type: 'session', ...sourceHeader }, { recovery: 'strict', validation: 'current' }) + for (const event of events) reader.decodeRow(event) + return reader.finish() +} + +describe('V3 to V4 source preservation', () => { + it('rejects required V3 developer events while preserving ignorable events and native V4 admission', () => { + const rows: SessionFormatEvent[] = [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'step/start', seq: 1, time: 2, data: { turn: 1, step: 1 } }, + { type: 'developer/message', seq: 2, time: 3, surfaceOp: 'append', data: { + turn: 1, step: 1, message: { id: 'developer', role: 'developer', source: { kind: 'tool-registry' }, content: [] }, + } }, + { type: 'step/end', seq: 3, time: 4, data: { turn: 1, step: 1 } }, + { type: 'turn/end', seq: 4, time: 5, data: { turn: 1, reason: { kind: 'completed' } } }, + ] + const before = structuredClone(rows) + expect(() => migrate(rows)).toThrow('format v3 contains unknown event type "developer/message" at seq 2') + expect(() => restore(rows)).toThrow('format v3 contains unknown event type "developer/message" at seq 2') + expect(() => restoreHistorical(rows, header)).toThrow('unknown event type') + const ignorable = rows.map(row => row.type === 'developer/message' ? { ...row, ignorable: true } : row) + expect(restore(ignorable).events).toEqual(ignorable.map(row => + row.type === 'developer/message' ? { ...row, type: 'plugin:developer/message' } : row)) + const native = sessionFormatCatalog.createRestore({ type: 'session', ...header, version: 4 }, { + recovery: 'strict', validation: 'current', + }) + for (const row of rows) native.decodeRow(row) + expect(native.finish().events).toEqual(rows) + expect(rows).toEqual(before) + }) + + it('rejects generic required V3 extensions before target vocabulary admission', () => { + const required = { ...fact, type: 'external/required' } + expect(() => migrate([required])).toThrow('format v3 contains unknown event type "external/required" at seq 0') + expect(() => restore([required])).toThrow('format v3 contains unknown event type "external/required" at seq 0') + const ignorable = { ...required, ignorable: true } + expect(restore([ignorable]).events).toEqual([{ ...ignorable, type: 'plugin:external/required' }]) + }) + + it('changes only the header version and retains event objects, payloads, timestamps, and coordinates', () => { + const rows = [fact, delivery(3)] + const before = JSON.stringify({ header, rows }) + expect(sessionFormatV3ToV4.migrateHeader(header)).toEqual({ ...header, version: 4 }) + expect(migrate(rows)).toEqual({ events: rows, cut: 0 }) + expect(migrate(rows).events[0]).toBe(fact) + expect(migrate(rows).events[1]).toBe(rows[1]) + expect(JSON.stringify({ header, rows })).toBe(before) + expect(stage().headerInheritedEventCount).toBe(0) + expect(migrate([])).toEqual({ events: [], cut: 0 }) + expect(restore(rows)).toEqual({ header: { ...header, version: 4 }, inheritedEventCount: 0, events: rows }) + expect(restore(rows)).toEqual(restore(rows)) + }) + + it('keeps interleaved stage state independent and derives an inherited cut unavailable before EOF', () => { + const inherited = stage({ ...header, isSeeded: true, parentSession: 'ancestor' }) + const local = stage() + const a = new SessionFormatEventCollector() + const b = new SessionFormatEventCollector() + expect(inherited.headerInheritedEventCount).toBeUndefined() + inherited.transformEvent(fact, a) + local.transformEvent(fact, b) + inherited.transformEvent(seed, a) + expect(local.finish(b)).toBe(0) + expect(inherited.finish(a)).toBe(1) + expect(a.values).toEqual([fact, seed]) + expect(b.values).toEqual([fact]) + expect(migrate([fact, seed], { ...header, isSeeded: true }, 1).cut).toBe(1) + }) + + it('consumes compact runs without changing their event values', () => { + const current = stage() + const output = new SessionFormatEventCollector() + current.transformRun({ runType: 'identity', eventCount: 1, firstSeq: 0, *expand() { yield fact } }, output) + expect(current.finish(output)).toBe(0) + expect(output.values[0]).toBe(fact) + }) + + it('rejects sparse sequences and inconsistent inheritance', () => { + expect(() => migrate([{ ...fact, seq: 1 }])).toThrow('dense') + expect(() => migrate([fact, seed])).toThrow('unseeded') + expect(() => migrate([fact], { ...header, isSeeded: true })).toThrow('inherited event count') + expect(() => migrate([fact, seed], { ...header, isSeeded: true }, 0)).toThrow('disagrees') + expect(() => migrate([fact, { ...seed, data: {} }], { ...header, isSeeded: true })).toThrow('inherited event count') + }) + + it('refuses target-generation delivery while retaining other generations unchanged', () => { + expect(() => migrate([fact, delivery(4)])).toThrow('claims target format v4') + expect(() => restore([fact, delivery(4)])).toThrow('claims target format v4') + for (const version of [undefined, 0, 1, 2, 3, 5, 99]) { + const marker = delivery(version) + expect(migrate([fact, marker]).events[1]).toBe(marker) + expect(restore([fact, marker]).events[1]).toEqual(marker) + } + }) + + it('checks active V3 coordinates before the delivery becomes historical', () => { + const marker = delivery(3) + const data = marker.data as SessionFormatJsonObject + for (const throughSeq of [-1, 1, 1.5]) { + expect(() => migrate([fact, { ...marker, data: { ...data, throughSeq } }])).toThrow('throughSeq') + } + expect(() => migrate([fact, { ...marker, data: { ...data, sessionId: '' } }])).toThrow('nonempty') + expect(() => restore([fact, { ...marker, data: { ...data, throughSeq: 1 } }])).toThrow('throughSeq') + const historical = { ...marker, data: { sessionId: 'ancestor', throughSeq: 500, sessionFormatVersion: 2 } } + expect(restore([fact, historical]).events[1]).toEqual(historical) + }) + + it('permits foreign active deliveries only inside a parent seed', () => { + const foreign = delivery(3, 'ancestor') + expect(() => migrate([fact, foreign])).toThrow('wrong Session') + expect(() => migrate([fact, foreign], { ...header, parentSession: 'ancestor' })).toThrow('wrong Session') + const rows = [fact, foreign, { ...seed, seq: 2 }] + expect(migrate(rows, { ...header, isSeeded: true, parentSession: 'ancestor' }).cut).toBe(2) + expect(() => migrate(rows, { ...header, isSeeded: true })).toThrow('wrong Session') + expect(() => migrate([fact, seed, { ...foreign, seq: 2 }], { ...header, isSeeded: true, parentSession: 'ancestor' })).toThrow('wrong Session') + }) + + it('retains unknown ignorable values and refuses unknown required events during strict catalog restoration', () => { + const opaque: SessionFormatEvent = { + type: 'external/opaque', seq: 0, time: -5, ignorable: true, + data: { nested: { seq: 40 }, content: ['opaque'] }, surfaceOp: { future: { ref: 9 } }, + } + expect(restore([opaque]).events).toEqual([{ ...opaque, type: 'plugin:external/opaque' }]) + const { ignorable: _ignorable, ...required } = opaque + expect(() => restore([required])).toThrow('unknown event type') + expect(() => restore([{ ...fact, time: 1.5 }])).toThrow('time') + expect(() => restore([{ ...fact, extra: 1 }])).toThrow(/field|member/) + }) + + it.each([0, 1, 2, 3])('restores a seeded V%i chain, including upstream cardinality changes, and reopens V4', (version) => { + const rows = [ + { type: 'turn/start', data: { turn: 1 } }, + { type: 'step/start', data: { turn: 1, step: 1 } }, + { type: 'user/message', data: { id: 'user', role: 'user', source: { kind: 'user' }, content: [{ type: 'text', text: 'input' }] }, surfaceOp: 'append' }, + { type: 'request/header', data: { header: { config: { provider: 'mock', model: 'mock' }, system: 'seed prompt' }, reason: 'initial' } }, + { type: 'step/end', data: { turn: 1, step: 1 } }, + { type: 'turn/end', data: { turn: 1, reason: { kind: 'completed' } } }, + { type: 'session/end-seed', data: version < 2 ? {} : { inherited: true } }, + ].map((event, seq): SessionFormatEvent => ({ ...event, seq, time: seq + 1 })) + const source = version === 3 ? restoreHistorical(rows, { ...header, version: 2, isSeeded: true }).events : rows + const physical = version < 2 + ? { type: 'session', version, id: header.id, createdAt: 1, delegationDepth: 0, parentSession: 'ancestor', seedLength: 6 } + : { type: 'session', ...header, version, isSeeded: true, parentSession: 'ancestor' } + const before = JSON.stringify({ physical, source }) + const reader = createSessionFormatCatalogWithChildren([]).createRestore(physical, { recovery: 'strict', validation: 'current' }) + for (const row of source) reader.decodeRow(version === 3 ? releasedV3SessionFormatCodec.encodeEvent(row) : row) + const artifact = reader.finish() + expect(artifact.header.version).toBe(4) + expect(artifact.inheritedEventCount).toBe(8) + expect(artifact.events.filter(event => event.type === 'system/message')).toHaveLength(2) + expect(artifact.events.at(-1)?.seq).toBe(8) + const reopened = sessionFormatCatalog.createRestore(sessionFormatCatalog.encodeCurrentHeader(artifact.header, 8), { + recovery: 'strict', validation: 'current', + }) + for (const event of artifact.events) reopened.decodeRow(sessionFormatCatalog.encodeCurrentEvent(event)) + expect(reopened.finish()).toEqual(artifact) + expect(JSON.stringify({ physical, source })).toBe(before) + }) + + it.each(['strict', 'recoverable'] as const)('retains delivery inside a nested inherited prefix during %s restoration', (recovery) => { + const physical = { type: 'session', ...header, isSeeded: true, parentSession: 'ancestor' } + const rows = [fact, seed, { ...delivery(3, 'ancestor'), seq: 2 }, { ...seed, seq: 3 }] + const decoder = releasedV3SessionFormatCodec.createDecoder(physical, 'strict') + const source = new SessionFormatEventCollector() + for (const row of rows) decoder.decodeRow(row, source) + const artifact = restoreReleasedV3Artifact({ header: decoder.header, events: source.values, + inheritedEventCount: decoder.finish(source) }, new Set(rows.map(row => row.type))) + expect(artifact.inheritedEventCount).toBe(3) + + const reader = createSessionFormatCatalogWithChildren([]).createRestore(physical, { recovery, validation: 'current' }) + for (const row of rows) reader.decodeRow(row) + expect(reader.finish()).toEqual({ ...artifact, header: { ...artifact.header, version: 4 } }) + }) + + it.each(['strict', 'recoverable'] as const)('refuses foreign delivery after the final inherited cut during %s restoration', (recovery) => { + const reader = createSessionFormatCatalogWithChildren([]).createRestore({ type: 'session', ...header, isSeeded: true, parentSession: 'ancestor' }, { + recovery, validation: 'current', + }) + for (const row of [fact, seed, { ...delivery(3, 'ancestor'), seq: 2 }, { ...seed, seq: 3 }, { ...delivery(3, 'ancestor'), seq: 4 }]) { + reader.decodeRow(row) + } + expect(() => reader.finish()).toThrow('wrong Session') + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/open-vocabulary.spec.ts b/packages/session/session-format-v3-to-v4/tests/open-vocabulary.spec.ts new file mode 100644 index 0000000000..834c661682 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/open-vocabulary.spec.ts @@ -0,0 +1,48 @@ +import { describe, expect, it } from 'vitest' +import type { SessionFormatArtifact, SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { version: 4, id: 'open-vocabulary', createdAt: 1, delegationDepth: 0, isSeeded: false } +function artifact(events: readonly { type: string; data: unknown; ignorable?: true; surfaceOp?: unknown }[]): SessionFormatArtifact { + return { header, inheritedEventCount: 0, events: events.map((event, seq) => ({ ...event, seq, time: seq })) as SessionFormatEvent[] } +} + +describe('known V4 event interpretation', () => { + it('keeps unknown ignorable payloads and coordinates opaque to every native semantic pass', () => { + const unknown = ['tool/result', 'system/message', 'request/header', 'session/title-llm-request', 'subagent/catalog', 'session-log-deepseek/delivery-accepted', 'compaction/start', 'compaction/end', 'session/end-seed'].map(type => ({ type, data: null, ignorable: true as const })) + const input = artifact([...unknown, { type: 'turn/start', data: { turn: 1 } }, { type: 'turn/end', data: { turn: 1 } }]) + const before = JSON.stringify(input) + expect(restoreReleasedV4Artifact(input, new Set(['turn/start', 'turn/end']))).toBe(input) + expect(JSON.stringify(input)).toBe(before) + expect(input.events.at(-1)?.seq).toBe(unknown.length + 1) + }) + + it('does not let an opaque end-seed clear an owned compaction', () => { + const input = artifact([ + { type: 'compaction/start', data: { compactionId: 'owner', turn: null } }, + { type: 'session/end-seed', data: {}, ignorable: true }, + { type: 'turn/start', data: { turn: 1 } }, + ]) + expect(() => restoreReleasedV4Artifact(input, new Set(['compaction/start', 'turn/start']))).toThrow(/crosses an open compaction/) + }) + + it('does not reinterpret an unknown ignorable user row through a known title citation', () => { + const input = artifact([ + { type: 'user/message', data: null, ignorable: true }, + { type: 'session/title', data: { title: 'title', source: { kind: 'generated' }, messageSeqs: [0] } }, + ]) + expect(() => restoreReleasedV4Artifact(input, new Set(['session/title']))).toThrow(/earlier human user\/message/) + }) + + it('still validates known events marked ignorable', () => { + const input = artifact([{ type: 'tool/result', data: null, ignorable: true }]) + expect(() => restoreReleasedV4Artifact(input, new Set(['tool/result']))).toThrow(/data must be an object/) + }) + + it('still validates unknown envelopes and refuses unknown required types', () => { + const required = artifact([{ type: 'external/event', data: null }]) + expect(() => restoreReleasedV4Artifact(required, new Set())).toThrow(/unknown event type/) + const input = artifact([{ type: 'external/event', data: null, ignorable: true }]) + expect(() => restoreReleasedV4Artifact({ ...input, events: [{ ...input.events[0]!, seq: 3 }] }, new Set())).toThrow(/not dense/) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/relationships.spec.ts b/packages/session/session-format-v3-to-v4/tests/relationships.spec.ts new file mode 100644 index 0000000000..5103fa8bf8 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/relationships.spec.ts @@ -0,0 +1,218 @@ +import { describe, expect, it } from 'vitest' +import { Session, SessionId, SessionLogOffset, type SessionEvent, type SessionHeader } from '@deepseek-ai/dsh-session' +import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' + +type Row = { type: string; data: Record; surfaceOp?: unknown; sourceEventSeqs?: number[]; ignorable?: true } +const row = (type: string, data: Record): Row => ({ type, data }) +const user = (kind = 'user') => ({ id: 'input', role: 'user', source: { kind }, content: [{ type: 'text', text: 'input' }] }) +const input = (kind = 'user'): Row => ({ ...row('user/message', user(kind)), surfaceOp: 'append' }) +const step = { turn: 1, step: 1 } +const call = { type: 'tool-call', id: 'call', name: 'read', arguments: '{}' } +const assistant = (content: unknown[] = [call]): Row => ({ + ...row('assistant/message', { ...step, stream: [], message: { id: 'assistant', role: 'assistant', source: { kind: 'model', provider: 'mock', model: 'mock' }, content } }), + surfaceOp: 'append', +}) +const result = (id = 'call', extra: Record = {}): Row => ({ + ...row('tool/result', { ...step, message: { id: 'result', role: 'tool', source: { kind: 'tool', callId: id }, toolCallId: id, content: [{ type: 'text', text: 'done' }], ...extra } }), + surfaceOp: 'append', +}) +const begin = () => [row('turn/start', { turn: 1 }), row('step/start', step)] +const end = () => [row('step/end', step), row('turn/end', { turn: 1, reason: { kind: 'completed' } })] +const toolCall = () => row('tool/call', { ...step, callId: 'call', name: 'read', arguments: '{}' }) +const request = () => row('request/header', { reason: 'initial', header: { config: { provider: 'mock', model: 'mock' } } }) + +/** Exercise physical JSON, catalog relationship admission, Session adoption, and derivation together. */ +function reopen(rows: readonly Row[], inherited = 0, seeded = false) { + const restore = sessionFormatCatalog.createRestore({ type: 'session', version: 4, id: 'native-relations', createdAt: 1, delegationDepth: 0, isSeeded: seeded, ...(seeded ? { parentSession: 'parent' } : {}) }, { recovery: 'strict', validation: 'current' }) + for (const [seq, candidate] of rows.entries()) { + const event = { ...candidate, seq, time: seq + 1 } as unknown as SessionFormatEvent + restore.decodeRow(JSON.parse(JSON.stringify(sessionFormatCatalog.encodeCurrentEvent(event)))) + } + const artifact = restore.finish() + expect(artifact.inheritedEventCount).toBe(inherited) + const session = Session.fromRestore(SessionId(artifact.header.id), artifact.events as SessionEvent[], artifact.header as unknown as SessionHeader, SessionLogOffset(inherited), 'detached') + return { artifact, messages: session.deriveMessages() } +} + +const compact = (): Row[] => [ + row('turn/start', { turn: 1 }), input(), + row('compaction/start', { compactionId: 'c', turn: 1, sourceCommandId: 'cmd' }), + row('compaction/summary', { compactionId: 'c', sourceCommandId: 'cmd', summary: [{ type: 'text', text: 'summary' }], shadowedRange: { start: 1, end: 1 }, shadowedSeqs: [1], shadowedTokenCount: 1, provider: 'mock', model: 'mock' }), + { ...input('compact-checkpoint'), data: { + ...user('compact-checkpoint'), id: 'checkpoint', source: { kind: 'compact-checkpoint', compactionId: 'c', sourceCommandId: 'cmd' }, + }, surfaceOp: { op: 'replace', startSeq: 1, endSeq: 1 }, sourceEventSeqs: [1, 2, 3] }, + row('compaction/end', { compactionId: 'c', sourceCommandId: 'cmd', turn: 1 }), + row('turn/end', { turn: 1, reason: { kind: 'completed' } }), +] +const change = (rows: Row[], index: number, data: Record): Row[] => + rows.map((candidate, i) => i === index ? { ...candidate, data: { ...candidate.data, ...data } } : candidate) +const retry = (changes: Record = {}) => row('llm/retry', { ...step, retryId: 'retry', retry: 1, provider: 'mock', policyKey: 'policy', ...changes }) +const retryStart = (changes: Record = {}) => row('llm/retry-started', { ...step, retryId: 'retry', retry: 1, ...changes }) +const dispatch = (type: 'start' | 'end', changes: Record = {}) => row(type === 'start' ? 'tool/ptc-dispatch-start' : 'tool/ptc-dispatch', { rootCallId: 'root', parentCallId: 'root', subCallId: 'child', name: 'read', arguments: { a: 1, b: 2 }, ...changes }) + +describe('mandatory V4 lifecycle restoration', () => { + it('retains valid ordinary tool exchanges and open interrupted tails', () => { + const rows = [...begin(), input(), request(), assistant(), toolCall(), result(), ...end()] + expect(reopen(rows).messages.map(message => message.role)).toEqual(['user', 'assistant', 'tool']) + for (let length = 0; length < rows.length; length += 1) expect(() => reopen(rows.slice(0, length))).not.toThrow() + }) + + it.each([ + ['turn order', [row('turn/start', { turn: 2 })]], + ['duplicate turn', [row('turn/start', { turn: 1 }), row('turn/start', { turn: 1 })]], + ['unopened turn end', [row('turn/end', { turn: 1 })]], + ['open step at turn end', [...begin(), row('turn/end', { turn: 1 })]], + ['unopened step', [row('step/start', step)]], + ['step sequence', [row('turn/start', { turn: 1 }), row('step/start', { turn: 1, step: 2 })]], + ['mismatched step end', [...begin(), row('step/end', { turn: 2, step: 1 })]], + ['assistant outside step', [assistant([])]], + ['assistant attempt outside step', [row('assistant/attempt', { ...step, stream: [] })]], + ['tool without advertisement', [...begin(), toolCall()]], + ['result without advertisement', [...begin(), result()]], + ['repeated advertisement', [...begin(), assistant([call, call])]], + ['changed tool name', [...begin(), assistant(), row('tool/call', { ...step, callId: 'call', name: 'other', arguments: '{}' })]], + ['changed tool arguments', [...begin(), assistant(), row('tool/call', { ...step, callId: 'call', name: 'read', arguments: '[]' })]], + ['repeated start', [...begin(), assistant(), toolCall(), toolCall()]], + ['unstarted success', [...begin(), assistant(), result()]], + ['repeated result', [...begin(), assistant(), toolCall(), result(), result()]], + ['unresolved advertised call', [...begin(), assistant(), ...end()]], + ['unresolved started call', [...begin(), assistant(), toolCall(), ...end()]], + ['header outside turn', [request()]], + ['context outside turn', [row('request/context', { provider: 'mock', model: 'mock' })]], + ] satisfies Array<[string, Row[]]>)('rejects %s', (_name, rows) => { + expect(() => reopen(rows)).toThrow() + }) + + it('accepts exact not-started repairs with preserved historical identity suffixes', () => { + const repaired = result('call', { id: 'interrupted-tool-result-call-200', isError: true, content: [{ type: 'text', text: 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.' }] }) + repaired.data['error'] = { name: 'ToolNotStartedError', code: 'TOOL_NOT_STARTED' } + expect(() => reopen([...begin(), assistant(), repaired, ...end()])).not.toThrow() + for (const extra of [{ id: 'made-up' }, { id: 'interrupted-tool-result-call-01' }, { id: 'interrupted-tool-result-call-9007199254740992' }, { content: [] }, { content: [{ type: 'text', text: 'invented repair' }] }]) { + const invalid = { ...repaired, data: { ...repaired.data, message: { ...(repaired.data['message'] as Record), ...extra } } } + expect(() => reopen([...begin(), assistant(), invalid])).toThrow() + } + expect(() => reopen([...begin(), assistant(), { ...repaired, sourceEventSeqs: [2] }])).toThrow() + expect(() => reopen([...begin(), assistant(), { ...repaired, data: { ...repaired.data, error: { name: 'OtherError', code: 'TOOL_NOT_STARTED' } } }])).toThrow() + }) + + it('preserves ignorable payloads and unknown attribution metadata', () => { + const message = { ...user('external'), source: JSON.parse('{"kind":"external","__proto__":{"x":1},"meta":{"a":2}}') as unknown } + const opaque: Row = { type: 'external/event', data: { arbitrary: true }, ignorable: true } + const rows = [opaque, { ...input(), data: message }] + const restored = reopen(rows) + expect(restored.artifact.events[0]?.data).toEqual(opaque.data) + expect(restored.messages[0]?.source).toEqual(message.source) + }) +}) + +describe('mandatory V4 compaction restoration', () => { + it('retains matching checkpoint sources and inherited unfinished compactions', () => { + expect(reopen(compact()).messages[0]?.source).toEqual({ kind: 'compact-checkpoint', compactionId: 'c', sourceCommandId: 'cmd' }) + const inherited = [row('compaction/start', { compactionId: 'old', turn: null }), ...begin(), ...end(), row('session/end-seed', { inherited: true })] + expect(() => reopen(inherited, 5, true)).not.toThrow() + expect(() => reopen([row('compaction/start', { compactionId: 'c', turn: null }), row('compaction/end', { compactionId: 'c', turn: null, error: 'cancelled' })])).not.toThrow() + expect(() => reopen(compact().slice(0, 5))).not.toThrow() + }) + + it.each([ + ['checkpoint identity', change(compact(), 4, { source: { kind: 'compact-checkpoint', compactionId: 'WRONG', sourceCommandId: 'cmd' } })], + ['checkpoint command', change(compact(), 4, { source: { kind: 'compact-checkpoint', compactionId: 'c', sourceCommandId: 'WRONG' } })], + ['summary identity', change(compact(), 3, { compactionId: 'WRONG' })], + ['end identity', change(compact(), 5, { compactionId: 'WRONG' })], + ['end turn', change(compact(), 5, { turn: null })], + ['start turn', change(compact(), 2, { turn: null })], + ['wrong span', change(compact(), 3, { shadowedSeqs: [] })], + ['missing span', change(compact(), 3, { shadowedRange: { start: 0, end: 0 }, shadowedSeqs: [0] })], + ['overlap', [...compact().slice(0, 3), row('compaction/start', { compactionId: 'second', turn: 1 })]], + ['repeated summary', [...compact().slice(0, 4), compact()[3]!]], + ['success without summary', [...compact().slice(0, 3), compact()[5]!]], + ['turn closes transaction', [...compact().slice(0, 3), compact()[6]!]], + ['unowned end', [row('compaction/end', { compactionId: 'c', turn: null })]], + ] satisfies Array<[string, Row[]]>)('rejects %s', (_name, rows) => { + expect(() => reopen(rows)).toThrow() + }) +}) + +describe('mandatory V4 dependent event restoration', () => { + it('accepts PTC nesting and settlements with equal argument objects', () => { + expect(() => reopen([...begin(), dispatch('start'), dispatch('start', { subCallId: 'grandchild', parentCallId: 'child' }), dispatch('end', { subCallId: 'grandchild', parentCallId: 'child' }), dispatch('end', { arguments: { b: 2, a: 1 } }), ...end()])).not.toThrow() + }) + + it.each([ + ['outside turn', [dispatch('start')]], + ['without start', [...begin(), dispatch('end')]], + ['duplicate start', [...begin(), dispatch('start'), dispatch('start')]], + ['duplicate settlement', [...begin(), dispatch('start'), dispatch('end'), dispatch('end')]], + ['unknown parent', [...begin(), dispatch('start', { parentCallId: 'unknown' })]], + ['root changes', [...begin(), dispatch('start'), dispatch('end', { rootCallId: 'different' })]], + ['arguments change', [...begin(), dispatch('start'), dispatch('end', { arguments: {} })]], + ['name changes', [...begin(), dispatch('start'), dispatch('end', { name: 'different' })]], + ] satisfies Array<[string, Row[]]>)('rejects PTC %s', (_name, rows) => { expect(() => reopen(rows)).toThrow() }) + + it('accepts retry chains, including retries scheduled after the step ends', () => { + expect(() => reopen([...begin(), request(), retry(), retryStart(), retry({ retry: 2 }), retryStart({ retry: 2 }), row('step/end', step), retry({ retry: 3 }), row('turn/end', { turn: 1, reason: { kind: 'completed' } })])).not.toThrow() + }) + + it.each([ + ['outside turn', [retry()]], + ['wrong step', [...begin(), request(), retry({ step: 2 })]], + ['wrong provider', [...begin(), request(), retry({ provider: 'other' })]], + ['skip attempt', [...begin(), request(), retry({ retry: 2 })]], + ['changed identity', [...begin(), request(), retry(), retry({ retry: 2, retryId: 'other' })]], + ['reused identity', [...begin(), request(), retry(), retry({ policyKey: 'other' })]], + ['unpaired start', [retryStart()]], + ['changed start coordinates', [...begin(), request(), retry(), retryStart({ step: 2 })]], + ['duplicate start', [...begin(), request(), retry(), retryStart(), retryStart()]], + ] satisfies Array<[string, Row[]]>)('rejects retry %s', (_name, rows) => { expect(() => reopen(rows)).toThrow() }) + + it('requires command completion to cite its run and an earlier non-command success event', () => { + const run = row('command/run', { commandId: 'cmd', name: 'test', source: { kind: 'user' } }) + const done = row('command/done', { commandId: 'cmd', kind: 'success', sourceEventSeq: 1 }) + expect(() => reopen([run, input(), done, row('command/done', { commandId: 'cmd', kind: 'error' })])).not.toThrow() + for (const rows of [[done], [run, run], [run, done], [run, input(), { ...done, data: { ...done.data, kind: 'error' } }], [run, input(), { ...done, data: { ...done.data, sourceEventSeq: 10 } }]]) { + expect(() => reopen(rows)).toThrow() + } + }) + + it('requires titles and durable title requests to cite earlier human messages', () => { + const title = row('session/title', { title: 'Example', source: { kind: 'generated' }, messageSeqs: [0] }) + const requestTitle = row('session/title-llm-request', { messageSeqs: [0], messages: [{ ...user('dsh-session-title-llm'), content: [{ type: 'text', text: 'historical frame with original coordinates' }] }] }) + expect(() => reopen([input(), title, requestTitle, row('session/title', { title: 'Manual', source: { kind: 'user' }, messageSeqs: [] })])).not.toThrow() + for (const rows of [[input('external'), title], [input(), { ...title, data: { ...title.data, source: { kind: 'user' } } }], [input(), { ...title, data: { ...title.data, messageSeqs: [0, 0] } }], [input(), { ...title, data: { ...title.data, messageSeqs: [1] } }], [input(), { ...requestTitle, data: { ...requestTitle.data, messages: [user()] } }], [input(), { ...requestTitle, data: { ...requestTitle.data, messageSeqs: [] } }]]) { + expect(() => reopen(rows)).toThrow() + } + }) +}) + + +describe('V4 protected system surface and malformed relationship inputs', () => { + const system = (): Row => ({ ...row('system/message', { ...step, message: { id: 'system', role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'text', text: 'system' }] } }), surfaceOp: 'append' }) + it('keeps the first system head protected across exact replacements', () => { + const replacement = { ...system(), surfaceOp: { op: 'replace', startSeq: 2, endSeq: 2 }, sourceEventSeqs: [2] } + expect(() => reopen([...begin(), system(), input(), replacement, system(), ...end()])).not.toThrow() + const prune = row('compaction/prune', { shadowedRange: { start: 3, end: 3 }, shadowedSeqs: [3], shadowedTokenCount: 1 }) + expect(() => reopen([...begin(), system(), input(), prune, ...end()])).not.toThrow() + for (const rows of [ + [...begin(), input(), system()], + [...begin(), input(), { ...replacement, sourceEventSeqs: [2] }], + [...begin(), system(), { ...input(), surfaceOp: { op: 'replace', startSeq: 2, endSeq: 2 }, sourceEventSeqs: [2] }], + [...begin(), system(), input(), { ...replacement, surfaceOp: { op: 'replace', startSeq: 2, endSeq: 3 }, sourceEventSeqs: [2, 3] }], + [...begin(), system(), input(), { ...replacement, surfaceOp: { op: 'replace', startSeq: 0, endSeq: 0 } }], + [...begin(), system(), input(), { ...replacement, surfaceOp: { op: 'replace', startSeq: 3, endSeq: 2 } }], + [...begin(), system(), input(), { ...replacement, sourceEventSeqs: [0] }], + [...begin(), system(), row('compaction/prune', { shadowedRange: { start: 2, end: 2 }, shadowedSeqs: [2] })], + ]) expect(() => reopen(rows)).toThrow() + }) + + it('rejects malformed relationship values and mismatched inherited transaction ownership', () => { + expect(() => reopen([row('command/run', { commandId: '' })])).toThrow() + expect(() => reopen([row('session/title', { messageSeqs: null })])).toThrow() + const inherited = [ + row('compaction/start', { compactionId: 'old', turn: null }), row('turn/start', { turn: 1 }), input(), + row('compaction/summary', { compactionId: 'old', shadowedRange: { start: 2, end: 2 }, shadowedSeqs: [2] }), + row('turn/end', { turn: 1, reason: { kind: 'completed' } }), row('session/end-seed', { inherited: true }), + ] + expect(() => reopen(inherited, 5, true)).toThrow(/does not match the open turn/) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/retired-content.spec.ts b/packages/session/session-format-v3-to-v4/tests/retired-content.spec.ts new file mode 100644 index 0000000000..9bffaced8a --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/retired-content.spec.ts @@ -0,0 +1,112 @@ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatEvent, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatCatalogWithChildren, historicalSessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { assertV4RowAdmission, releasedV4SessionFormatCodec, restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { version: 4, id: 'retired-content', createdAt: 1, isSeeded: false, delegationDepth: 0 } +const wrapper: SessionFormatJsonObject = { + type: 'tool-result', toolCallId: 'retired-call', content: [{ type: 'text', text: 'saved result' }], +} +const content = [wrapper] +const user = { id: 'user', role: 'user', source: { kind: 'user' }, content } +const message = (role: string): SessionFormatJsonObject => ({ + id: role, role, content, + source: role === 'assistant' ? { kind: 'model', provider: 'test', model: 'test' } + : role === 'tool' ? { kind: 'tool', callId: 'call' } : { kind: `${role}-prompt` }, + ...(role === 'tool' ? { toolCallId: 'call' } : {}), +}) +const cases: readonly { name: string; type: string; data: SessionFormatJsonObject; error?: RegExp }[] = [ + { name: 'user message', type: 'user/message', data: user }, + ...['system', 'developer', 'assistant'].map(role => ({ + name: `${role} message`, type: `${role}/message`, data: { turn: 1, step: 1, message: message(role) }, + ...(role === 'system' ? { error: /rejects retired tool-result/ } : {}), + })), + { name: 'native tool message', type: 'tool/result', data: { turn: 1, step: 1, message: message('tool') } }, + { name: 'queued input', type: 'agent/inbox/spliced', data: { target: 'next-turn', start: 0, inserted: [user] } }, + { name: 'title request', type: 'session/title-llm-request', data: { messages: [user] } }, + { name: 'compaction summary', type: 'compaction/summary', data: { summary: content } }, + { name: 'compaction raw output', type: 'compaction/summary', data: { summary: [], rawOutput: content } }, + { name: 'PTC result', type: 'tool/ptc-dispatch', data: { content } }, + { name: 'team message', type: 'team/message/queued', data: { message: user } }, + ...['assistant/message', 'assistant/attempt'].flatMap(type => ['block-start', 'block-end'].map(kind => ({ + name: `${type} stream ${kind}`, type, data: { + turn: 1, step: 1, message: { ...message('assistant'), content: [] }, + stream: [{ type: 'chunk', elapsedMs: 0, chunk: kind === 'block-start' + ? { type: kind, index: 0, blockType: 'tool-result' } + : { type: kind, index: 0, block: wrapper } }], + }, + }))), +] + +function row(type: string, data: SessionFormatJsonObject): SessionFormatEvent { + return { type, data, seq: 0, time: 1 } +} + +describe('retired tool-result content admission', () => { + it.each(cases)('refuses $name in native encoding, restoration and recoverable suffixes', ({ type, data, error = /released tool-result wrapper/ }) => { + const event = row(type, data) + const before = structuredClone(event) + expect(() => releasedV4SessionFormatCodec.encodeEvent(event)).toThrow(error) + expect(() => restoreReleasedV4Artifact({ header, inheritedEventCount: 0, events: [event] }, new Set([type]))) + .toThrow(error) + for (const recovery of ['strict', 'recoverable'] as const) { + const decoder = releasedV4SessionFormatCodec.createDecoder({ type: 'session', ...header }, recovery) + const collector = new SessionFormatEventCollector() + if (recovery === 'recoverable') decoder.decodeRow(null, collector) + expect(() => { decoder.decodeRow(event, collector) }).toThrow(error) + } + expect(event).toEqual(before) + }) + + it('refuses a V3 user wrapper at the V4 target while leaving the released reader and source intact', () => { + const event = { ...row('user/message', user), surfaceOp: 'append' } as SessionFormatEvent + const before = structuredClone(event) + const physical = { type: 'session', ...header, version: 3 } + const historical = historicalSessionFormatCatalog.createRestore(physical, { recovery: 'strict', validation: 'current' }) + historical.decodeRow(event) + expect(historical.finish().events).toEqual([event]) + const current = createSessionFormatCatalogWithChildren([]).createRestore(physical, { recovery: 'strict', validation: 'current' }) + expect(() => { current.decodeRow(event); current.finish() }).toThrow(/released tool-result wrapper/) + expect(event).toEqual(before) + }) + + it('interprets ignorable developer content only for a reader that knows the event, or for encoding', () => { + const event = { ...row('developer/message', { turn: 1, step: 1, message: message('developer') }), ignorable: true } + const collector = new SessionFormatEventCollector() + const decoder = releasedV4SessionFormatCodec.createDecoder({ type: 'session', ...header }, 'strict') + decoder.decodeRow(event, collector) + expect(collector.values).toEqual([event]) + expect(() => { assertV4RowAdmission(event, new Set()) }).not.toThrow() + expect(() => { assertV4RowAdmission(event, new Set(['developer/message'])) }).toThrow(/released tool-result wrapper/) + expect(() => releasedV4SessionFormatCodec.encodeEvent(event)).toThrow(/released tool-result wrapper/) + const artifact = { header, inheritedEventCount: 0, events: [event] } + expect(restoreReleasedV4Artifact(artifact, new Set())).toBe(artifact) + }) + + it('keeps tool arguments, replay state, schemas, nested metadata, and unknown ignorable payloads opaque', () => { + const rows: SessionFormatEvent[] = [ + row('user/message', { ...user, content: [{ type: 'text', text: 'text', metadata: wrapper }], replayState: { content } }), + row('tool/call', { arguments: JSON.stringify(wrapper), metadata: { content } }), + row('tool/ptc-dispatch', { content: [{ type: 'text', text: 'result' }], arguments: wrapper }), + row('request/header', { header: { config: { provider: 'test', model: 'test' }, tools: [{ + name: 'example', description: '', parameters: { type: 'object', examples: [wrapper] }, + }] } }), + { ...row('future/opaque', { content, message: user, stream: [{ type: 'chunk', chunk: { type: 'block-end', block: wrapper } }] }), ignorable: true }, + ] + for (const event of rows) { + const before = structuredClone(event) + const encoded = releasedV4SessionFormatCodec.encodeEvent(event) + const collector = new SessionFormatEventCollector() + releasedV4SessionFormatCodec.createDecoder({ type: 'session', ...header }, 'strict').decodeRow(encoded, collector) + expect(collector.values).toEqual([before]) + expect(event).toEqual(before) + } + const opaque = rows.at(-1)! + const migrated = createSessionFormatCatalogWithChildren([]).createRestore({ type: 'session', ...header, version: 3 }, { + recovery: 'strict', validation: 'current', + }) + migrated.decodeRow(opaque) + expect(migrated.finish().events).toEqual([{ ...opaque, type: 'plugin:future/opaque' }]) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/retired-syntax.spec.ts b/packages/session/session-format-v3-to-v4/tests/retired-syntax.spec.ts new file mode 100644 index 0000000000..8a121b2389 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/retired-syntax.spec.ts @@ -0,0 +1,41 @@ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector, type SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { releasedV4SessionFormatCodec, restoreReleasedV4Artifact } from '../src/index.ts' + +const header = { version: 4, id: 'native-syntax', createdAt: 1, delegationDepth: 0, isSeeded: false } +const physical = { type: 'session', ...header } +const request = (data: unknown): SessionFormatEvent => ({ type: 'request/header', seq: 1, time: 1, data }) as SessionFormatEvent +const turn: SessionFormatEvent = { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } } + +describe('native retired syntax admission', () => { + it('rejects retired headers and PTC tags in strict reads, encoding, and recoverable suffixes', () => { + const invalid = [ + request(null), request({ header: null }), request({ header: { config: { provider: 'mock', model: 'mock' }, system: '' } }), + { type: 'tool/code-dispatch-start', seq: 1, time: 1, data: {} }, + { type: 'tool/code-dispatch', seq: 1, time: 1, data: {} }, + ] + for (const event of invalid) { + expect(() => sessionFormatCatalog.encodeCurrentEvent(event)).toThrow() + const read = sessionFormatCatalog.createRestore(physical, { recovery: 'strict', validation: 'current' }) + read.decodeRow(turn) + expect(() => { read.decodeRow(event) }).toThrow() + const scanner = releasedV4SessionFormatCodec.createDecoder(physical, 'recoverable') + const output = new SessionFormatEventCollector() + scanner.decodeRow(null, output) + expect(() => { scanner.decodeRow(event, output) }).toThrow() + const artifact = { header, inheritedEventCount: 0, events: [turn, event] } + expect(() => restoreReleasedV4Artifact(artifact, new Set([turn.type, event.type]))).toThrow() + } + }) + + it('keeps known request fields open and obsolete ignorable tags opaque', () => { + const rows = [turn, request({ reason: 'initial', header: { config: { provider: 'mock', model: 'mock' }, extra: true } }), + { type: 'tool/code-dispatch-start', seq: 2, time: 1, data: { unknown: true }, ignorable: true }, + { type: 'tool/code-dispatch', seq: 3, time: 1, data: null, ignorable: true }, + ] as SessionFormatEvent[] + const read = sessionFormatCatalog.createRestore(physical, { recovery: 'strict', validation: 'current' }) + for (const event of rows) read.decodeRow(JSON.parse(JSON.stringify(sessionFormatCatalog.encodeCurrentEvent(event)))) + expect(read.finish().events).toEqual(rows) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/sources.spec.ts b/packages/session/session-format-v3-to-v4/tests/sources.spec.ts new file mode 100644 index 0000000000..83a54b2262 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/sources.spec.ts @@ -0,0 +1,102 @@ +import { describe, expect, it } from 'vitest' +import type { SessionFormatEvent, SessionFormatJsonObject, SessionFormatJsonValue } from '@deepseek-ai/dsh-session-format' +import { mapEventMessages, rewritePluginSource, rewriteV3MessageSource } from '../src/sources.ts' + +function event(type: string, data: SessionFormatJsonObject): SessionFormatEvent { + return { type, seq: 0, time: 1, data } +} + +const identity = (message: SessionFormatJsonObject): SessionFormatJsonObject => message + +describe('mapEventMessages', () => { + it('returns events whose data is not an object', () => { + const row = { type: 'turn/start', seq: 0, time: 1, data: 'nope' } as unknown as SessionFormatEvent + expect(mapEventMessages(row, identity)).toBe(row) + }) + + it('transforms the user/message payload and preserves identity when unchanged', () => { + const message: SessionFormatJsonObject = { id: 'u', role: 'user', source: { kind: 'user' }, content: [] } + const row = event('user/message', message) + expect(mapEventMessages(row, identity)).toBe(row) + expect(mapEventMessages(row, value => ({ ...value, id: 'u2' })).data).toEqual({ ...message, id: 'u2' }) + }) + + it('transforms the message payload of system, assistant, and tool/result rows', () => { + const message: SessionFormatJsonObject = { id: 's', role: 'system', source: { kind: 'system-prompt' }, content: [] } + const row = event('system/message', { turn: 1, step: 1, message }) + expect(mapEventMessages(row, identity)).toBe(row) + expect((mapEventMessages(row, value => ({ ...value, id: 's2' })).data as SessionFormatJsonObject)['message']).toEqual({ ...message, id: 's2' }) + }) + + it('refuses a message payload that is not an object', () => { + expect(() => mapEventMessages(event('system/message', { message: 'nope' }), identity)).toThrow(/requires a message/) + }) + + it('transforms message arrays on spliced and title-request rows', () => { + const message: SessionFormatJsonObject = { id: 'u', role: 'user', source: { kind: 'user' }, content: [] } + const spliced = event('agent/inbox/spliced', { target: 'next-turn', start: 0, inserted: [message] }) + expect(mapEventMessages(spliced, identity)).toBe(spliced) + expect((mapEventMessages(spliced, value => ({ ...value, id: 'u2' })).data as SessionFormatJsonObject)['inserted']).toEqual([{ ...message, id: 'u2' }]) + const title = event('session/title-llm-request', { messages: [message] }) + expect(mapEventMessages(title, identity)).toBe(title) + expect((mapEventMessages(title, value => ({ ...value, id: 'u2' })).data as SessionFormatJsonObject)['messages']).toEqual([{ ...message, id: 'u2' }]) + }) + + it('refuses a message array that is not an array and members that are not objects', () => { + expect(() => mapEventMessages(event('agent/inbox/spliced', { inserted: 'nope' }), identity)).toThrow(/requires message array/) + expect(() => mapEventMessages(event('agent/inbox/spliced', { inserted: ['nope'] }), identity)).toThrow(/requires message objects/) + }) + + it('returns unrelated events unchanged', () => { + const row = event('turn/start', { turn: 1 }) + expect(mapEventMessages(row, identity)).toBe(row) + }) +}) + +describe('rewritePluginSource', () => { + it('rewrites renamed and role-sensitive producers, dropping the plugin field', () => { + expect(rewritePluginSource({ kind: 'plugin', plugin: 'tools-ptc' }, 1, 'user')).toEqual({ kind: 'ptc-mode' }) + expect(rewritePluginSource({ kind: 'plugin', plugin: 'tools-code-mode' }, 1, 'user')).toEqual({ kind: 'ptc-mode' }) + expect(rewritePluginSource({ kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, 1, 'system')).toEqual({ kind: 'system-prompt' }) + expect(rewritePluginSource({ kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, 1, 'user')).toEqual({ kind: 'runtime-context' }) + expect(rewritePluginSource({ kind: 'plugin', plugin: 'external', extra: true }, 1, 'user')).toEqual({ kind: 'plugin:external', extra: true }) + }) + + it('refuses a plugin field that is not a string', () => { + const plugins: readonly SessionFormatJsonValue[] = [null, 7] + for (const plugin of plugins) { + expect(() => rewritePluginSource({ kind: 'plugin', plugin }, 3, 'user')).toThrow(/not canonical/) + } + }) + + it('namespaces external plugin names while retaining released first-party producers', () => { + for (const plugin of ['plugin', 'user', 'model', 'tool', 'system-prompt', 'runtime-context', 'compact-checkpoint', 'ptc-mode', 'compact-basic', 'auto-review']) { + expect(rewritePluginSource({ kind: 'plugin', plugin }, 3, 'user')).toEqual({ kind: `plugin:${plugin}` }) + } + expect(rewritePluginSource({ kind: 'plugin', plugin: 'agent-instructions', form: 'instructions', changes: [] }, 3, 'user')) + .toEqual({ kind: 'agent-instructions', form: 'instructions', changes: [] }) + expect(rewritePluginSource({ kind: 'plugin', plugin: 'tool-jobs' }, 3, 'user')).toEqual({ kind: 'tool-jobs' }) + expect(rewritePluginSource({ kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, 3, 'system')).toEqual({ kind: 'system-prompt' }) + }) +}) + +describe('external V3 source identities', () => { + it.each(['', 'acme', 'plugin:x', 'source:x', 'message', 'x/y', '\ud800', '__proto__'])('prefixes the complete plugin name %j', (name) => { + expect(rewritePluginSource({ kind: 'plugin', plugin: name }, 1, 'user')).toEqual({ kind: `plugin:${name}` }) + }) + + it.each(['acme', 'plugin:acme', 'source:acme', 'message', 'x/y', '\ud800', '__proto__'])('preserves direct source kind %j and its metadata', (kind) => { + const source = { kind, payload: { kind: 'plugin', plugin: kind } } + expect(rewriteV3MessageSource(source, 1, 'user')).toBe(source) + }) + + it('preserves native V3 sources and converts plugin wrappers', () => { + const source = { kind: 'tool', callId: 'call', extra: true } + expect(rewriteV3MessageSource(source, 1, 'user')).toBe(source) + expect(rewriteV3MessageSource({ kind: 'plugin', plugin: 'compact' }, 1, 'user')).toEqual({ kind: 'compact-checkpoint' }) + }) + + it.each([null, 0, ''])('rejects type-invalid source kind %j', (kind) => { + expect(() => rewriteV3MessageSource({ kind }, 1, 'user')).toThrow(/requires a nonempty kind/) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/system-message.spec.ts b/packages/session/session-format-v3-to-v4/tests/system-message.spec.ts new file mode 100644 index 0000000000..a5de21b6cf --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/system-message.spec.ts @@ -0,0 +1,59 @@ +import { describe, expect, it } from 'vitest' +import { SessionFormatEventCollector, type SessionFormatEvent } from '@deepseek-ai/dsh-session-format' +import { createSessionFormatCatalogWithChildren, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { releasedV4SessionFormatCodec } from '../src/codec.ts' + +const header = { type: 'session', version: 4, id: 'system-fields', createdAt: 1, delegationDepth: 0, isSeeded: false } +const migrated = createSessionFormatCatalogWithChildren([]).createRestore({ ...header, version: 3 }, { recovery: 'strict', validation: 'current' }) +for (const event of [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'step/start', seq: 1, time: 1, data: { turn: 1, step: 1 } }, + { type: 'system/message', seq: 2, time: 1, surfaceOp: 'append', data: { turn: 1, step: 1, message: { + id: 'system', role: 'system', source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, content: [], + } } }, +]) migrated.decodeRow(event) +const source = (migrated.finish().events[2]?.data as { message: { source: object } }).message.source +const attachment = { attachmentId: 'sha256:image', mediaType: 'image/png', bytes: 1, width: 1, height: 1 } +const message = (content: unknown) => ({ id: 'system', role: 'system', source, content }) +const row = (data: unknown): SessionFormatEvent => ({ type: 'system/message', seq: 2, time: 1, surfaceOp: 'append', data }) as SessionFormatEvent + +function restored(data: unknown) { + const read = sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' }) + for (const event of [{ type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, { type: 'step/start', seq: 1, time: 1, data: { turn: 1, step: 1 } }, row(data)]) { + read.decodeRow(JSON.parse(JSON.stringify(sessionFormatCatalog.encodeCurrentEvent(event)))) + } + return read.finish() +} + +describe('native system-message fields', () => { + it('preserves required fields and extra JSON on known and extensible block types', () => { + const content = [ + { type: 'text', text: '', extension: { keep: true } }, { type: 'reasoning', text: 'reasoning' }, + { type: 'tool-call', id: 'call', name: 'read', arguments: '{}' }, { type: 'file', extension: true }, + { type: 'image', attachment }, { type: 'image', attachment: { + ...attachment, name: 'name', originalDimensions: { width: 1, height: 2 }, extension: true, + } }, + ] + const data = { turn: 1, step: 1, message: message(content), extra: true } + expect(restored(data).events[2]?.data).toEqual(data) + }) + + it('rejects malformed fields before a recoverable scanner can discard the row', () => { + const contents = [ + null, [null], [{}], [{ type: '' }], [{ type: 'text', text: 1 }], [{ type: 'tool-call', id: '' }], + [{ type: 'tool-call', id: 'id', name: '' }], [{ type: 'tool-call', id: 'id', name: 'name', arguments: null }], + [{ type: 'tool-result', toolCallId: 'call', content: [] }], + ...[null, { ...attachment, mediaType: 'text/plain' }, { ...attachment, attachmentId: '' }, { ...attachment, bytes: -1 }, { ...attachment, width: 0 }, { ...attachment, height: 0 }, { ...attachment, name: 1 }, { ...attachment, originalDimensions: null }, { ...attachment, originalDimensions: { width: 0, height: 1 } }, { ...attachment, originalDimensions: { width: 1, height: 0 } }].map(value => ({ type: 'image', attachment: value })).map(block => [block]), + ] + const invalid = [null, { turn: 0, step: 1 }, { turn: 1, step: 0 }, { turn: 1, step: 1, message: null }, + ...[{ ...message([]), id: '' }, { ...message([]), role: 'user' }, ...contents.map(message)].map(value => ({ turn: 1, step: 1, message: value })), + ] + for (const data of invalid) { + expect(() => restored(data)).toThrow() + const read = releasedV4SessionFormatCodec.createDecoder(header, 'recoverable') + const output = new SessionFormatEventCollector() + read.decodeRow(null, output) + expect(() => { read.decodeRow(row(data), output) }).toThrow() + } + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/tool-role.spec.ts b/packages/session/session-format-v3-to-v4/tests/tool-role.spec.ts new file mode 100644 index 0000000000..8e753cb3ff --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/tool-role.spec.ts @@ -0,0 +1,458 @@ +import { describe, expect, it } from 'vitest' +import type { SessionFormatEvent, SessionFormatHeader, SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import { SessionFormatEventCollector, SessionFormatUnsupportedMigrationError } from '@deepseek-ai/dsh-session-format' +import { createToolResultMessage, ToolCallId } from '@deepseek-ai/dsh-llm' +import { createSessionFormatV3ToV4, releasedV4SessionFormatCodec, restoreReleasedV4Artifact, sessionFormatV3ToV4 } from '../src/index.ts' +import { assertV4ToolResultMessage, liftToolResult } from '../src/tool-role.ts' + +const header = { version: 4, id: 'tool-role', createdAt: 1, isSeeded: false, delegationDepth: 0 } + +function event(seq: number, type: string, data: SessionFormatJsonObject): SessionFormatEvent { + return { type, seq, time: seq + 1, data } +} + +/** Released V3 canonical user-role wrapper tool/result message. */ +function wrapperMessage(callId = 'call-1', text = 'result'): SessionFormatJsonObject { + return { + id: `tool-result-${callId}`, + role: 'user', + source: { kind: 'tool', callId }, + content: [{ + type: 'tool-result', + toolCallId: callId, + isError: false, + content: [{ type: 'text', text }], + }], + } +} + +/** Native V4 first-class tool-role message. */ +function firstClassMessage(callId = 'call-1', text = 'result', isError: boolean | undefined = false): SessionFormatJsonObject { + return { + id: `tool-result-${callId}`, + role: 'tool', + source: { kind: 'tool', callId }, + toolCallId: callId, + content: [{ type: 'text', text }], + ...(isError === undefined ? {} : { isError }), + } +} + +describe('V4 tool-role view and lift', () => { + it.each([false, true])('serializes lifted result fields in current writer order with isError=%s', (isError) => { + const content = [{ type: 'text' as const, text: 'result' }] + const current = createToolResultMessage({ callId: ToolCallId('call-1'), content, isError }) + const row = event(0, 'tool/result', { turn: 1, step: 1, message: { + ...wrapperMessage(), + content: [{ type: 'tool-result', toolCallId: 'call-1', content, isError }], + } }) + const target = (liftToolResult(row).data as SessionFormatJsonObject)['message'] + expect(JSON.stringify(target)).toBe(JSON.stringify({ ...current, id: 'tool-result-call-1' })) + }) + + it.each([undefined, false, true])('preserves outer fields without activating their target names with isError=%s', (isError) => { + const metadata = JSON.parse('{"__proto__":{"saved":"prototype"},"constructor":{"saved":"constructor"},"extension":{"saved":true}}') as SessionFormatJsonObject + const content = [{ type: 'text', text: 'result' }] + const message: SessionFormatJsonObject = { + ...metadata, ...wrapperMessage(), toolCallId: 'call-1', ...(isError === undefined ? {} : { isError }), + content: [{ type: 'tool-result', toolCallId: 'call-1', content, ...(isError === undefined ? {} : { isError }) }], + } + const row = { ...event(0, 'tool/result', { turn: 1, step: 1, message }), surfaceOp: 'append' } as SessionFormatEvent + const before = structuredClone(row) + const lifted = liftToolResult(row) + const target = (lifted.data as SessionFormatJsonObject)['message'] as SessionFormatJsonObject + expect(target).toEqual({ id: message['id'], role: 'tool', source: message['source'], toolCallId: 'call-1', content, + ...(isError === undefined ? {} : { isError, 'plugin:message:isError': isError }), + 'plugin:message:toolCallId': 'call-1', + 'plugin:message:__proto__': metadata['__proto__'], 'plugin:message:constructor': metadata['constructor'], + 'plugin:message:extension': metadata['extension'], + }) + expect(Object.hasOwn(target, 'plugin:message:__proto__')).toBe(true) + expect(Object.hasOwn(target, 'plugin:message:constructor')).toBe(true) + expect(Object.getPrototypeOf(target)).toBe(Object.prototype) + expect(row).toEqual(before) + expect(JSON.parse(JSON.stringify(releasedV4SessionFormatCodec.encodeEvent(lifted)))).toEqual(lifted) + }) + + it.each([ + ['toolCallId', 'other-call', false], + ['isError', true, false], + ['isError', true, undefined], + ['isError', 'false', false], + ] as const)('keeps outer %s data separate from the interpreted result', (field, value, isError) => { + const row = event(0, 'tool/result', { turn: 1, step: 1, message: { + ...wrapperMessage(), [field]: value, + content: [{ type: 'tool-result', toolCallId: 'call-1', content: [], ...(isError === undefined ? {} : { isError }) }], + } }) + const before = structuredClone(row) + const target = (liftToolResult(row).data as SessionFormatJsonObject)['message'] as SessionFormatJsonObject + expect(target[`plugin:message:${field}`]).toEqual(value) + expect(target['toolCallId']).toBe('call-1') + expect(target['isError']).toBe(isError) + expect(row).toEqual(before) + }) + + it('preserves an outer flag without adding an absent result flag', () => { + const row = event(0, 'tool/result', { turn: 1, step: 1, message: { + ...wrapperMessage(), isError: false, content: [{ type: 'tool-result', toolCallId: 'call-1', content: [] }], + } }) + expect(liftToolResult(row).data).toMatchObject({ message: { role: 'tool', 'plugin:message:isError': false } }) + expect((liftToolResult(row).data as SessionFormatJsonObject)['message']).not.toHaveProperty('isError') + }) + + it.each(['extension', '__proto__', 'constructor'])('preserves result-owned %s without adding a core field', (field) => { + const wrapper = Object.fromEntries([ + ['type', 'tool-result'], ['toolCallId', 'call-1'], ['content', []], [field, { saved: true }], + ]) as SessionFormatJsonObject + const row = event(0, 'tool/result', { turn: 1, step: 1, message: { ...wrapperMessage(), content: [wrapper] } }) + const before = structuredClone(row) + const target = (liftToolResult(row).data as SessionFormatJsonObject)['message'] as SessionFormatJsonObject + expect(target[`plugin:result:${field}`]).toEqual({ saved: true }) + expect(Object.hasOwn(target, `plugin:result:${field}`)).toBe(true) + expect(Object.getPrototypeOf(target)).toBe(Object.prototype) + expect(row).toEqual(before) + }) + + it('keeps repeated owner names and already-prefixed field names distinct', () => { + const row = event(0, 'tool/result', { turn: 1, step: 1, message: { + ...wrapperMessage(), note: 'outer', 'plugin:result:note': 'outer prefixed', + content: [{ type: 'tool-result', toolCallId: 'call-1', content: [], note: 'inner', 'plugin:message:note': 'inner prefixed' }], + } }) + expect(liftToolResult(row).data).toMatchObject({ message: { + 'plugin:message:note': 'outer', 'plugin:message:plugin:result:note': 'outer prefixed', + 'plugin:result:note': 'inner', 'plugin:result:plugin:message:note': 'inner prefixed', + } }) + }) + + it('lifts a released wrapper into the native tool-role message', () => { + const wrapperRow = { ...event(0, 'tool/result', { turn: 1, step: 1, message: wrapperMessage() }), surfaceOp: 'append' } as SessionFormatEvent + const lifted = liftToolResult(wrapperRow) + expect(lifted.data).toEqual({ + turn: 1, + step: 1, + message: firstClassMessage(), + }) + }) + + it('omits isError when a released wrapper did not persist the flag', () => { + const row = event(0, 'tool/result', { + turn: 1, step: 1, + message: { + ...wrapperMessage(), + content: [{ type: 'tool-result', toolCallId: 'call-1', content: [{ type: 'text', text: 'result' }] }], + }, + }) + expect(liftToolResult(row).data).toMatchObject({ message: { role: 'tool', content: [{ type: 'text', text: 'result' }] } }) + expect((liftToolResult(row).data as SessionFormatJsonObject)['message']).not.toHaveProperty('isError') + }) + + it('rejects a released wrapper with a non-boolean isError flag', () => { + const row = event(0, 'tool/result', { + turn: 1, step: 1, + message: { + ...wrapperMessage(), + content: [{ type: 'tool-result', toolCallId: 'call-1', isError: 'yes', content: [] }], + }, + }) + expect(() => liftToolResult(row)).toThrow(/tool-result isError must be boolean/) + }) + + it('passes non-tool rows through the wrapper conversion', () => { + const row = event(0, 'user/message', { content: [], source: { kind: 'user' }, role: 'user', id: 'u' }) + expect(liftToolResult(row)).toBe(row) + }) + + it('preserves isError and repair identity across the lift', () => { + const repair = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { + id: 'interrupted-tool-result-call-1-0', + role: 'user', + source: { kind: 'tool', callId: 'call-1' }, + content: [{ + type: 'tool-result', + toolCallId: 'call-1', + isError: true, + content: [{ + type: 'text', + text: 'The tool call was interrupted before the Harness recorded it as started. Retry it if it is still needed.', + }], + }], + }, + error: { name: 'ToolNotStartedError', code: 'TOOL_NOT_STARTED' }, + }) + const lifted = liftToolResult(repair) + expect((lifted.data as SessionFormatJsonObject)['message']).toMatchObject({ + role: 'tool', + toolCallId: 'call-1', + isError: true, + id: 'interrupted-tool-result-call-1-0', + }) + expect((lifted.data as SessionFormatJsonObject)['error']).toEqual({ name: 'ToolNotStartedError', code: 'TOOL_NOT_STARTED' }) + }) + + it('refuses nested released results without discarding their identity or error status', () => { + const row = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { + ...wrapperMessage(), + content: [{ + type: 'tool-result', + toolCallId: 'call-1', + isError: false, + content: [{ + type: 'tool-result', + toolCallId: 'nested-call', + isError: true, + content: [{ type: 'text', text: 'hidden' }], + }], + }], + }, + }) + const before = structuredClone(row) + expect(() => liftToolResult(row)).toThrow(SessionFormatUnsupportedMigrationError) + expect(() => liftToolResult(row)).toThrow('unsupported by this converter') + expect(row).toEqual(before) + }) + + it('rejects a released wrapper with extra top-level content blocks', () => { + const row = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { + ...wrapperMessage(), + content: [ + { type: 'tool-result', toolCallId: 'call-1', isError: false, content: [{ type: 'text', text: 'result' }] }, + { type: 'text', text: 'extra' }, + ], + }, + }) + expect(() => liftToolResult(row)).toThrow(/exactly one tool-result wrapper/) + }) +}) + +describe('released V4 codec with native tool-role rows', () => { + it('encodes and decodes a first-class tool result unchanged', () => { + const row = { ...event(0, 'tool/result', { turn: 1, step: 1, message: firstClassMessage() }), surfaceOp: 'append' } as SessionFormatEvent + const encoded = releasedV4SessionFormatCodec.encodeEvent(row) + expect(encoded).toEqual(row) + const collector = new SessionFormatEventCollector() + const decoder = releasedV4SessionFormatCodec.createDecoder( + { type: 'session', ...header }, + 'strict', + ) + decoder.decodeRow(row, collector) + expect(collector.values).toEqual([row]) + }) + + it('rejects a released-wrapper row in the current V4 decoder', () => { + const wrapperRow = { ...event(0, 'tool/result', { turn: 1, step: 1, message: wrapperMessage() }), surfaceOp: 'append' } as SessionFormatEvent + const collector = new SessionFormatEventCollector() + const decoder = releasedV4SessionFormatCodec.createDecoder( + { type: 'session', ...header }, + 'strict', + ) + expect(() => { decoder.decodeRow(wrapperRow, collector) }).toThrow(/requires a tool-role message/) + }) + + it('keeps native semantic failures hard even in recoverable mode', () => { + const row = { ...event(0, 'tool/result', { turn: 1, step: 1, message: firstClassMessage('call-1', 'result', 'yes' as never) }), surfaceOp: 'append' } as SessionFormatEvent + const decoder = releasedV4SessionFormatCodec.createDecoder({ type: 'session', ...header }, 'recoverable') + expect(() => { decoder.decodeRow(row, new SessionFormatEventCollector()) }).toThrow(/isError must be boolean/) + }) + + it('refuses a native row whose error metadata lacks the message isError flag', () => { + const bad = event(0, 'tool/result', { + turn: 1, + step: 1, + message: firstClassMessage('call-1', 'result', false), + error: { name: 'ToolNotStartedError', code: 'TOOL_NOT_STARTED' }, + }) + expect(() => releasedV4SessionFormatCodec.encodeEvent(bad)).toThrow(/error metadata for a non-error tool result/) + }) + + it('restores a first-class artifact through the released V3 relationship rules', () => { + const artifact = { + header: header as unknown as SessionFormatHeader, + inheritedEventCount: 0, + events: [ + event(0, 'turn/start', { turn: 1 }), + event(1, 'step/start', { turn: 1, step: 1 }), + { + type: 'assistant/message', seq: 2, time: 3, surfaceOp: 'append', + data: { + turn: 1, step: 1, + message: { + id: 'a-1', role: 'assistant', + content: [{ type: 'tool-call', id: 'call-1', name: 'bash', arguments: '{}' }], + source: { kind: 'model', provider: 'mock', model: 'mock' }, + }, + stream: [], + }, + }, + { + type: 'tool/call', seq: 3, time: 4, + data: { turn: 1, step: 1, callId: 'call-1', name: 'bash', arguments: '{}' }, + }, + { + type: 'tool/result', seq: 4, time: 5, surfaceOp: 'append', + data: { turn: 1, step: 1, message: firstClassMessage('call-1') }, + }, + event(5, 'step/end', { turn: 1, step: 1 }), + event(6, 'turn/end', { turn: 1, reason: { kind: 'completed' } }), + ], + } + expect(restoreReleasedV4Artifact(artifact as never, new Set(artifact.events.map(item => item.type)))).toBe(artifact) + expect(artifact.events[4]).toMatchObject({ data: { message: { role: 'tool', toolCallId: 'call-1' } } }) + }) +}) + +describe('V3 to V4 edge lifts released tool results', () => { + function migrate(rows: readonly SessionFormatEvent[]) { + const targetHeader = sessionFormatV3ToV4.migrateHeader({ ...header, version: 3 }) + const stage = createSessionFormatV3ToV4([]).createStage({ + sourceHeader: { ...header, version: 3 }, + targetHeader, + sourceInheritedEventCount: 0, + sourceKind: 'decoded', + }) + const collector = new SessionFormatEventCollector() + for (const [seq, row] of rows.entries()) stage.transformEvent({ ...row, seq }, collector) + return { header: targetHeader, cut: stage.finish(collector), events: collector.values } + } + + it('lifts a released wrapper tool result into the native message', () => { + const rows = [ + event(0, 'turn/start', { turn: 1 }), + event(1, 'step/start', { turn: 1, step: 1 }), + { + type: 'tool/result', seq: 2, time: 3, surfaceOp: 'append', + data: { turn: 1, step: 1, message: wrapperMessage() }, + }, + ] + const output = migrate(rows) + expect(output.events[2]?.data).toEqual({ turn: 1, step: 1, message: firstClassMessage() }) + }) + + it('keeps non-tool rows intact and expands runs through the same transform', () => { + const row = event(0, 'turn/start', { turn: 1 }) + const run = { runType: 'identity', firstSeq: 0, eventCount: 1, expand: () => [row] } + const emitted: SessionFormatEvent[] = [] + const stage = createSessionFormatV3ToV4([]).createStage({ + sourceHeader: { ...header, version: 3 }, + targetHeader: { ...header }, + sourceInheritedEventCount: 0, + sourceKind: 'decoded', + }) + stage.transformRun(run, { + emitEvent: (value) => { emitted.push(value) }, + emitRun: () => { throw new Error('unexpected run emission') }, + }) + expect(emitted).toEqual([{ ...row, seq: 0 }]) + }) +}) + +describe('native tool-result validation', () => { + function native(overrides: SessionFormatJsonObject = {}): SessionFormatEvent { + return event(0, 'tool/result', { turn: 1, step: 1, message: { ...firstClassMessage(), ...overrides } }) + } + + function raw(data: unknown): SessionFormatEvent { + return { type: 'tool/result', seq: 0, time: 1, data } as SessionFormatEvent + } + + it('accepts a native message and ignores rows of other event types', () => { + expect(() => { assertV4ToolResultMessage(native()) }).not.toThrow() + expect(() => { assertV4ToolResultMessage(event(0, 'user/message', { role: 'user', content: [] })) }).not.toThrow() + }) + + it('refuses data and messages that are not objects', () => { + expect(() => { assertV4ToolResultMessage(raw('nope')) }).toThrow(/data must be an object/) + expect(() => { assertV4ToolResultMessage(raw({ message: 'nope' })) }).toThrow(/message must be an object/) + }) + + it('refuses ids that are not non-empty strings', () => { + expect(() => { assertV4ToolResultMessage(native({ id: '' })) }).toThrow(/string id/) + expect(() => { assertV4ToolResultMessage(native({ id: 7 })) }).toThrow(/string id/) + }) + + it('refuses a message that is not the tool role', () => { + expect(() => { assertV4ToolResultMessage(native({ role: 'user' })) }).toThrow(/tool-role message/) + }) + + it('refuses a tool call id that does not match the tool source', () => { + expect(() => { assertV4ToolResultMessage(native({ toolCallId: 'other' })) }).toThrow(/matching its tool source/) + expect(() => { assertV4ToolResultMessage(native({ toolCallId: '' })) }).toThrow(/matching its tool source/) + expect(() => { assertV4ToolResultMessage(native({ source: { kind: 'tool', callId: 'other' } })) }).toThrow(/matching its tool source/) + expect(() => { assertV4ToolResultMessage(native({ source: 'nope' })) }).toThrow(/matching its tool source/) + }) + + it('refuses a source that is not the tool source', () => { + expect(() => { assertV4ToolResultMessage(native({ source: { kind: 'model', callId: 'call-1' } })) }).toThrow(/requires a tool source/) + }) + + it('refuses content that is not an array', () => { + expect(() => { assertV4ToolResultMessage(native({ content: 'nope' })) }).toThrow(/array content/) + }) + + it('refuses an isError flag that is not boolean', () => { + expect(() => { assertV4ToolResultMessage(native({ isError: 'yes' })) }).toThrow(/isError must be boolean/) + }) + + it('round trips a native message without an isError flag', () => { + const message: SessionFormatJsonObject = { + id: 'tool-result-call-1', + role: 'tool', + source: { kind: 'tool', callId: 'call-1' }, + toolCallId: 'call-1', + content: [{ type: 'text', text: 'result' }], + } + const row = { ...event(0, 'tool/result', { turn: 1, step: 1, message }), surfaceOp: 'append' } as SessionFormatEvent + expect(liftToolResult(row)).toBe(row) + }) + + it('refuses a released wrapper without its wrapper block', () => { + const row = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { id: 'x', role: 'user', source: { kind: 'tool', callId: 'call-1' }, content: [] }, + }) + expect(() => liftToolResult(row)).toThrow(/exactly one tool-result wrapper/) + }) + + it('refuses wrapper rows with invalid source or content fields', () => { + const invalidSource = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { id: 'x', role: 'user', source: 'nope', content: [] }, + }) + expect(() => liftToolResult(invalidSource)).toThrow(/exactly one tool-result wrapper/) + + const invalidContent = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { id: 'x', role: 'user', source: { kind: 'tool', callId: 'call-1' }, content: 'nope' }, + }) + expect(() => liftToolResult(invalidContent)).toThrow(/exactly one tool-result wrapper/) + + const invalidNestedContent = event(0, 'tool/result', { + turn: 1, + step: 1, + message: { + ...wrapperMessage(), + content: [{ type: 'tool-result', toolCallId: 'call-1', content: 'nope' }], + }, + }) + expect(() => liftToolResult(invalidNestedContent)).toThrow(/tool-result content must be an array/) + }) + + it('refuses a native message that still contains a released wrapper', () => { + expect(() => { + assertV4ToolResultMessage(native({ + content: [{ type: 'tool-result', toolCallId: 'call-1', content: [] }], + })) + }).toThrow(/must not contain a released tool-result wrapper/) + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tests/validation.spec.ts b/packages/session/session-format-v3-to-v4/tests/validation.spec.ts new file mode 100644 index 0000000000..2d3c447842 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tests/validation.spec.ts @@ -0,0 +1,172 @@ +import { describe, expect, it } from 'vitest' +import type { + SessionFormatArtifact, + SessionFormatHeader, + SessionFormatJsonObject, +} from '@deepseek-ai/dsh-session-format' +import { + assertReleasedV4Header, + restoreReleasedV4Artifact, +} from '@deepseek-ai/dsh-session-format-v3-to-v4' +import { assertReleasedV4Artifact as assertReleasedV4PhysicalArtifact } from '../src/testing/validation.ts' + +const KNOWN = new Set(['turn/start', 'step/start', 'assistant/message', 'tool/call', 'tool/result', 'step/end', 'turn/end', 'user/message', 'session/end-seed']) + +function header(overrides: Partial> = {}): SessionFormatHeader { + return { + version: 4, + id: 'v4-session', + createdAt: 1, + isSeeded: false, + delegationDepth: 0, + ...overrides, + } +} + +function artifact(events: readonly Record[], h = header(), inherited = 0): SessionFormatArtifact { + return { + header: h, + inheritedEventCount: inherited, + events: events as unknown as SessionFormatArtifact['events'], + } +} + +/** One canonical released-v4 turn: call a tool and receive its result. */ +function conversation(): Record[] { + const message = ( + id: string, + role: string, + content: SessionFormatJsonObject[], + source: SessionFormatJsonObject, + ): SessionFormatJsonObject => ( + { id, role, content, source } + ) + return [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'step/start', seq: 1, time: 2, data: { turn: 1, step: 1 } }, + { + type: 'assistant/message', seq: 2, time: 3, surfaceOp: 'append', + data: { + turn: 1, step: 1, + message: message('assistant-1', 'assistant', [ + { type: 'text', text: 'calling' }, + { type: 'tool-call', id: 'call-1', name: 'bash', arguments: '{}' }, + ], { kind: 'model', provider: 'mock', model: 'mock' }), + stream: [{ type: 'chunk', time: 3, chunk: { type: 'block-end', index: 1, block: { type: 'tool-call', id: 'call-1', name: 'bash', arguments: '{}' } } }], + }, + }, + { + type: 'tool/call', seq: 3, time: 4, + data: { turn: 1, step: 1, callId: 'call-1', name: 'bash', arguments: '{}' }, + }, + { + type: 'tool/result', seq: 4, time: 5, surfaceOp: 'append', + data: { + turn: 1, step: 1, + message: { ...message('tool-1', 'tool', [{ type: 'text', text: 'ok' }], { kind: 'tool', callId: 'call-1' }), + toolCallId: 'call-1', isError: false }, + }, + }, + { type: 'step/end', seq: 5, time: 6, data: { turn: 1, step: 1 } }, + { type: 'turn/end', seq: 6, time: 7, data: { turn: 1, reason: { kind: 'completed' } } }, + ] +} + +describe('assertReleasedV4Header', () => { + it('accepts the minimal and complete header images', () => { + expect(() => { assertReleasedV4Header(header()) }).not.toThrow() + expect(() => { assertReleasedV4Header(header({ + cwd: '/work', parentSession: 'parent', origin: 'subagent', agentPreset: 'headless', isSeeded: true, + })) }).not.toThrow() + }) + + it('refuses malformed headers', () => { + const malformed: Array<[string, Record, RegExp]> = [ + ['wrong version', { ...header(), version: 2 }, /expected format v4/], + ['non-string id', { ...header(), id: 3 }, /id must be a string/], + ['non-count createdAt', { ...header(), createdAt: 'x' }, /createdAt/], + ['non-count delegationDepth', { ...header(), delegationDepth: -1 }, /delegationDepth/], + ['non-boolean isSeeded', { ...header(), isSeeded: 1 }, /isSeeded must be boolean/], + ['relative cwd', { ...header(), cwd: 'work' }, /cwd must be absolute/], + ['non-string parentSession', { ...header(), parentSession: 3 }, /parentSession must be a string/], + ['non-string agentPreset', { ...header(), agentPreset: 3 }, /agentPreset must be a string/], + ['invalid origin', { ...header(), origin: 'other' }, /origin must be "subagent"/], + ] + for (const [name, value, message] of malformed) { + expect(() => { assertReleasedV4Header(value) }, name).toThrow(message) + } + }) +}) + +describe('restoreReleasedV4Artifact', () => { + it('validates dense envelopes, cuts, and event vocabulary', () => { + const valid = artifact(conversation()) + expect(restoreReleasedV4Artifact(valid, KNOWN)).toBe(valid) + + expect(() => restoreReleasedV4Artifact(artifact(conversation(), header({ isSeeded: true }), 20), KNOWN)) + .toThrow(/inherited event count exceeds its events/) + expect(() => restoreReleasedV4Artifact(artifact([ + { type: 'session/end-seed', seq: 0, time: 1, data: { inherited: true } }, + ], header(), 0), KNOWN)) + .toThrow(/format v4 unseeded Session contains an inherited end-seed marker/) + expect(() => restoreReleasedV4Artifact(artifact(conversation(), header(), 1), KNOWN)) + .toThrow(/unseeded format v4 Session has inherited events/) + }) + + it('validates only the envelope in physical mode', () => { + const unknown = conversation() + unknown.splice(2, 0, { type: 'campaign/unknown', seq: 0, time: 1, data: { x: 1 } }) + for (const [index, item] of unknown.entries()) (item as { seq: number }).seq = index + expect(() => { assertReleasedV4PhysicalArtifact(artifact(unknown)) }).not.toThrow() + expect(() => restoreReleasedV4Artifact(artifact(unknown), KNOWN)) + .toThrow(/unknown event type/) + }) + + it('refuses unknown non-ignorable types and admits ignorable ones', () => { + const unknown = conversation() + unknown.splice(2, 0, { type: 'campaign/unknown', seq: 99, time: 1, data: { x: 1 } }) + expect(() => restoreReleasedV4Artifact(artifact(unknown), KNOWN)) + .toThrow(/unknown event type/) + const ignorable = conversation() + ignorable.splice(0, 0, { + type: 'campaign/unknown', seq: 0, time: 1, ignorable: true, data: { x: 1 }, + }) + for (const [index, item] of ignorable.entries()) (item as { seq: number }).seq = index + expect(() => restoreReleasedV4Artifact(artifact(ignorable), new Set([...KNOWN, 'campaign/unknown']))) + .not.toThrow() + }) + + it('enforces V4-owned event density', () => { + expect(() => restoreReleasedV4Artifact(artifact([ + { type: 'turn/start', time: 1, data: {} }, + ]), KNOWN)).toThrow(/is not dense/) + expect(() => restoreReleasedV4Artifact(artifact([ + conversation()[0]!, { ...conversation()[1]!, seq: 3 }, + ]), KNOWN)).toThrow(/is not dense/) + }) + + it('enforces end-seed marker agreement', () => { + const marker = (seq: number, inherited: boolean) => ({ + type: 'session/end-seed', seq, time: 1, data: { ...(inherited ? { inherited: true } : {}) }, + }) + expect(() => restoreReleasedV4Artifact( + artifact([marker(0, true)], header({ isSeeded: true }), 0), + new Set([...KNOWN, 'session/end-seed']), + )).not.toThrow() + expect(() => restoreReleasedV4Artifact( + artifact([marker(0, false), marker(1, true)], header({ isSeeded: true }), 0), + new Set([...KNOWN, 'session/end-seed']), + )).toThrow(/seeded header disagrees/) + expect(() => restoreReleasedV4Artifact( + artifact([marker(0, true)], header(), 0), + new Set([...KNOWN, 'session/end-seed']), + )).toThrow(/unseeded Session contains an inherited end-seed marker/) + }) + + it('refuses non-object records and non-string event types', () => { + expect(() => restoreReleasedV4Artifact(artifact([{ type: 3, seq: 0, time: 1, data: {} }]), KNOWN)) + .toThrow(/unknown event type/) + expect(() => restoreReleasedV4Artifact(artifact([null as never]), KNOWN)) + .toThrow() + }) +}) diff --git a/packages/session/session-format-v3-to-v4/tsconfig.json b/packages/session/session-format-v3-to-v4/tsconfig.json new file mode 100644 index 0000000000..373e4c24f6 --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types" + }, + "include": ["src"], + "references": [ + { "path": "../../../vendor/cordis" }, + { "path": "../session-format" }, + { "path": "../session-format-v2-to-v3" } + ] +} diff --git a/packages/session/session-format-v3-to-v4/tsdown.config.ts b/packages/session/session-format-v3-to-v4/tsdown.config.ts new file mode 100644 index 0000000000..caaa1aefad --- /dev/null +++ b/packages/session/session-format-v3-to-v4/tsdown.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: ['lib/types/index.js'], + outDir: 'lib', + format: ['esm'], + platform: 'node', + target: 'es2024', + fixedExtension: false, + dts: false, + clean: false, +}) diff --git a/packages/session/session-log-deepseek/src/index.ts b/packages/session/session-log-deepseek/src/index.ts index 2e48cf6b52..3fb27d4320 100644 --- a/packages/session/session-log-deepseek/src/index.ts +++ b/packages/session/session-log-deepseek/src/index.ts @@ -77,6 +77,7 @@ function wireEvent(event: SessionEvent): DeepSeekSessionLogWireEvent { ...event.ignorable === undefined ? {} : { ignorable: event.ignorable }, } switch (event.type) { + case 'developer/message': case 'system/message': case 'user/message': case 'tool/result': diff --git a/packages/session/session-log-deepseek/tests/feedback-composition.spec.ts b/packages/session/session-log-deepseek/tests/feedback-composition.spec.ts index c31cce05c6..7bf73bc369 100644 --- a/packages/session/session-log-deepseek/tests/feedback-composition.spec.ts +++ b/packages/session/session-log-deepseek/tests/feedback-composition.spec.ts @@ -78,8 +78,12 @@ it('uploads freeform feedback and message put/edit/delete through the unchanged try { const user = createUserMessage({ content: [{ type: 'text', text: 'Question' }], source: { kind: 'user' } }) const assistant = createAssistantMessage({ content: [{ type: 'text', text: 'Answer' }], source: { provider: 'deepseek-official', model: 'deepseek-v4-flash' } }) + session.append('turn/start', { turn: 1 }) + session.append('step/start', { turn: 1, step: 1 }) session.append('user/message', user, { surfaceOp: 'append' }) session.append('assistant/message', { message: assistant, stream: [], turn: 1, step: 1 }, { surfaceOp: 'append' }) + session.append('step/end', { turn: 1, step: 1 }) + session.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) const messages = session.deriveMessages() recordFeedback(session, { text: ' The session needs a clearer explanation. ' }) const created = await ctx.messageFeedback.put({ sessionId: session.id, messageId: assistant.id, rating: 'negative', note: 'Explain the result.', ifVersion: null }) diff --git a/packages/session/session-log-deepseek/tests/upload.spec.ts b/packages/session/session-log-deepseek/tests/upload.spec.ts index abd4fafc67..298a38cf23 100644 --- a/packages/session/session-log-deepseek/tests/upload.spec.ts +++ b/packages/session/session-log-deepseek/tests/upload.spec.ts @@ -8,9 +8,11 @@ import SessionStore, { SessionSeq, type CreateSessionOptions, type SessionEvent, + type SessionHeader, } from '@deepseek-ai/dsh-session' +import { createSessionFormatCatalogWithChildren } from '@deepseek-ai/dsh-session-format-catalog' import DeepSeekLlmApiExtensionRegistry from '@deepseek-ai/dsh-deepseek-llm-api-extensions' -import { createAssistantMessage, createSystemMessage, createUserMessage } from '@deepseek-ai/dsh-llm' +import { createDeveloperMessage, createAssistantMessage, createSystemMessage, createUserMessage } from '@deepseek-ai/dsh-llm' import type { JsonValue } from '@deepseek-ai/dsh-util-values' import * as SessionLogDeepSeek from '../src/index.ts' import type { DeepSeekSessionLogExtension, DeepSeekSessionLogWireEvent, DeepSeekSessionLogWireSurfaceOp } from '../src/types.ts' @@ -83,6 +85,19 @@ describe('incremental DeepSeek session-log upload', () => { }>() }) + it('uploads developer changes with their placement and source-event references', async () => { + const { ctx, session } = await harness('wire-developer') + const message = createDeveloperMessage({ content: [{ type: 'tool-addition', toolName: 'search' }], source: { kind: 'tool-registry' } }) + const headerSeq = session.append('request/header', { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [{ name: 'search', description: 'Search', parameters: {} }] } }).seq + const first = session.append('developer/message', { turn: 1, step: 1, headerSeq, message }, { surfaceOp: 'append' }) + session.append('developer/message', { + turn: 1, step: 1, + message: createDeveloperMessage({ content: [{ type: 'tool-removal', toolName: 'search' }], source: { kind: 'tool-registry' } }), + }, { surfaceOp: { op: 'replace', startSeq: first.seq, endSeq: first.seq }, sourceEventSeqs: [first.seq] }) + const prepared = await ctx.deepseekLlmApiExtensions.prepare({ body: body(), signal: SIGNAL, sessionId: session.id }) + expect(prepared.fields.dsh_session_log?.events).toEqual(session.snapshotEvents()) + }) + it('uploads Assistant provider metadata only through its embedded stream', async () => { const { ctx, session } = await harness('wire-assistant') const assistant = session.append('assistant/message', { @@ -108,13 +123,13 @@ describe('incremental DeepSeek session-log upload', () => { it('uploads system append and replacement placement with unchanged data and source-event references', async () => { const { ctx, session } = await harness('wire-system') - const headData = { turn: 1, step: 1, message: createSystemMessage('head', 'fixture'), extra: { retained: true } } + const headData = { turn: 1, step: 1, message: createSystemMessage('head'), extra: { retained: true } } const head = session.append('system/message', headData, { surfaceOp: 'append' }) session.append('system/message', { - turn: 1, step: 2, message: createSystemMessage('later', 'fixture'), + turn: 1, step: 2, message: createSystemMessage('later'), }, { surfaceOp: 'append' }) session.append('system/message', { - turn: 1, step: 3, message: createSystemMessage('new head', 'fixture'), + turn: 1, step: 3, message: createSystemMessage('new head'), }, { surfaceOp: { op: 'replace', startSeq: head.seq, endSeq: head.seq }, sourceEventSeqs: [head.seq] }) const prepared = await ctx.deepseekLlmApiExtensions.prepare({ body: body(), signal: SIGNAL, sessionId: session.id }) expect(prepared.fields.dsh_session_log?.events).toEqual(session.snapshotEvents()) @@ -215,6 +230,36 @@ describe('incremental DeepSeek session-log upload', () => { expect(forkPayload.fields.dsh_session_log).toMatchObject({ afterSeq: -1, throughSeq: fork.session.seq - 1 }) }) + it('uploads a migrated V3 log from the beginning before resuming current-generation acknowledgements', async () => { + const id = SessionId('migrated-v3-delivery') + const reader = createSessionFormatCatalogWithChildren([]).createRestore({ + type: 'session', version: 3, id, createdAt: 1, isSeeded: false, delegationDepth: 0, + }, { recovery: 'strict', validation: 'current' }) + reader.decodeRow({ type: 'feedback/record', seq: 0, time: 2, data: { text: 'retained' } }) + reader.decodeRow({ + type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 3, + data: { sessionId: id, throughSeq: 0, sessionFormatVersion: 3 }, + }) + const artifact = reader.finish() + const session = Session.fromRestore(id, artifact.events as SessionEvent[], + artifact.header as unknown as SessionHeader, SessionLogOffset(artifact.inheritedEventCount), 'detached') + const { ctx } = await harness('delivery-migration-owner') + ctx.effect(() => ctx.sessions.enter(session)) + + const first = await ctx.deepseekLlmApiExtensions.prepare({ body: body(), signal: SIGNAL, sessionId: id }) + expect(first.fields.dsh_session_log).toMatchObject({ sessionFormatVersion: SESSION_FORMAT_VERSION, afterSeq: -1 }) + expect(first.fields.dsh_session_log?.events[0]?.seq).toBe(0) + expect(first.fields.dsh_session_log?.events[1]).toMatchObject({ data: { sessionFormatVersion: 3, throughSeq: 0 } }) + const throughSeq = session.seq - 1 + await first.accept() + expect(session.snapshotEvents().at(-1)?.data).toEqual({ sessionId: id, sessionFormatVersion: SESSION_FORMAT_VERSION, throughSeq }) + + const second = await ctx.deepseekLlmApiExtensions.prepare({ body: body(), signal: SIGNAL, sessionId: id }) + expect(second.fields.dsh_session_log?.afterSeq).toBe(throughSeq) + expect(second.fields.dsh_session_log?.events.map(event => event.seq)).toEqual([throughSeq + 1]) + expect(session.eventAt(SessionSeq(1))?.data).toMatchObject({ sessionFormatVersion: 3, throughSeq: 0 }) + }) + it('takes the maximum watermark when concurrent acceptances settle out of order', async () => { const { ctx, session } = await harness('concurrent') session.append('turn/start', { turn: 1 }) diff --git a/packages/session/session-persistence-jsonl/README.i18n.yaml b/packages/session/session-persistence-jsonl/README.i18n.yaml index b0af7efebf..1589a1d5c7 100644 --- a/packages/session/session-persistence-jsonl/README.i18n.yaml +++ b/packages/session/session-persistence-jsonl/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/session/session-persistence-jsonl/README.md -README.md: fc431ff27bcd236c4d44b8d3e7b20d4291b936d4 -README.zh.md: 3b265bf43f058d4c0711568df156825febed4d24 +README.md: 96c333d9f845943ff44c8d5d539c40d07b9dc0f6 +README.zh.md: 71126dd909c92aabdee5c07d23505f708dc5e038 diff --git a/packages/session/session-persistence-jsonl/README.md b/packages/session/session-persistence-jsonl/README.md index fc431ff27b..96c333d9f8 100644 --- a/packages/session/session-persistence-jsonl/README.md +++ b/packages/session/session-persistence-jsonl/README.md @@ -79,7 +79,11 @@ The current-generation scanner applies the current codec owner’s structural ad ### Reading the logs -`open(id, 'read'|'write')` selects the highest canonical generation. Current input follows the ordinary fast path. For historical input, a read open decodes and migrates the source once, validates the current logical result, and returns it without publishing a successor. A write open reuses that revision-keyed preparation when available, or performs the same preparation, then encodes a same-directory temporary file in bounded chunks, verifies it in a Worker Thread, rechecks the source revision, and publishes the current successor without overwrite before returning. The source remains byte-identical. Source drift after preparation rejects that write open without replacing the logical history already returned to readers; a later write open prepares the new revision. The backend marks decoded event graphs `shared-frozen` when it freezes them before memoization; handle reads and slices preserve that state, including empty slices. Only an unmaterialized pending log reports `detached`. `stat(id)` and `list()` select and translate only the highest generation header without reading event rows or starting migration; snapshots carry `sizeBytes` and a best-effort stat-derived revision for the selected file. With `compression: 'none'`, the log is newline-delimited text an external reader can consume directly; the compressed default must be read through the backend. +`open(id, 'read'|'write')` selects the highest canonical generation. Current input follows the ordinary fast path. For historical input, a read open decodes and migrates the source once, validates the current logical result, and returns it without publishing a successor. A write open reuses that revision-keyed preparation when available, or performs the same preparation, then encodes a same-directory temporary file in bounded chunks, verifies it in a Worker Thread, rechecks the source revision, and publishes the current successor without overwrite before returning. The source remains byte-identical. Source drift after preparation rejects that write open without replacing the logical history already returned to readers; a later write open prepares the new revision. The backend marks decoded event graphs `shared-frozen` when it freezes them before memoization; every nested object and array is frozen, and handle reads and slices preserve that state, including empty slices. Only an unmaterialized pending log reports `detached`. `stat(id)` and `list()` select and translate only the highest generation header without reading event rows or starting migration; snapshots carry the selected file’s `sizeBytes` and a best-effort revision. Current revisions identify that file; historical revisions also fingerprint the selected files across the persistence root, so child changes invalidate cached logical events. Fingerprinting reads filesystem metadata only; unrelated changes conservatively invalidate historical revisions. One `list()` call shares a corpus fingerprint across its historical entries. With `compression: 'none'`, the log is newline-delimited text an external reader can consume directly; the compressed default must be read through the backend. + +Historical body preparation completes the parent catalog through [V3→V4](../session-format-v3-to-v4/README.md). It scans headers, decodes only direct children one at a time, and retains compact descriptor evidence plus source revisions. It rechecks membership and revisions before returning preparation, reusing it, and publishing. Source drift invalidates preparation: read open retries preparation once automatically, while write open refuses publication. Diagnostics name the changed, added, removed, or unreadable child path. An unsupported selected generation or unreadable header anywhere else in the scan refuses migration because it cannot establish complete membership. Ordinary listing still skips those files. Missing, unsupported, or multiple child descriptors prevent only that child’s catalog backfill; existing parent entries and child logs remain available. Invalid fields in exactly one supported own descriptor still report an unsupported format; malformed child events, JSON records, and compressed data report corruption at the child path. Filesystem errors and cancellation retain their original errors. Current V4 opens bypass this scan and validate catalog fields, uniqueness, and current delivery ownership before exposing events. + +Historical `stat` and `list` revisions require metadata work proportional to the root’s Session count. Fresh body preparation scans all selected headers and decodes direct-child bodies; memo reuse still scans membership and checks revisions. Read-only access never publishes an upgrade, so cold processes and evicted preparations repeat that work. Current V4 body reads and revisions avoid the historical corpus scan. See the [measured costs and diagnostic command](../../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md#catalog-scan-measurements). ----- @@ -93,7 +97,7 @@ This section explains the physical encoding and write path; the observable contr ### Design concept -The backend owns its complete storage runtime (`src/storage.ts`): `JsonlSessionHandle` carries the per-handle mutation chain, the routed live-event buffer with its fixed batching window and single-flight drain, monotonic reads, and idempotent close; a tracker holds the in-process single-writer claims, the open-handle set teardown sweeps, and the created-but-unmaterialized pending sessions the backend's own session listeners route into. Historical body reads share one per-session Decode/Migrate preparation, and a bounded revision-keyed memo lets an immediate observe-to-resume handoff reuse that parse; the backend deep-freezes each event graph once before memoization, so later handle reads reuse it without copying or freezing. Only a write open publishes the prepared successor. The package deliberately exposes only its default plugin export plus configuration types — the concrete class is not a named export, so consumers couple to `ctx.sessionPersistence`, and the shared seam suites (`runPersistenceContract`/`runLiveWritePathContract`) pin its observable behavior. Its change token is a best-effort file revision: device, inode, size, and nanosecond timestamps identify one log for `stat`/`list`, for the stable-read loop that retries a read torn by a concurrent append, and for the pre-publication source check. +The backend owns its complete storage runtime (`src/storage.ts`): `JsonlSessionHandle` carries the per-handle mutation chain, the routed live-event buffer with its fixed batching window and single-flight drain, monotonic reads, and idempotent close; a tracker holds the in-process single-writer claims, the open-handle set teardown sweeps, and the created-but-unmaterialized pending sessions the backend's own session listeners route into. Historical body reads share one per-session Decode/Migrate preparation, and a bounded revision-keyed memo lets an immediate observe-to-resume handoff reuse that parse; the backend deep-freezes each event graph once before memoization, so later handle reads reuse it without copying or freezing. Only a write open publishes the prepared successor. The package deliberately exposes only its default plugin export plus configuration types — the concrete class is not a named export, so consumers couple to `ctx.sessionPersistence`, and the shared seam suites (`runPersistenceContract`/`runLiveWritePathContract`) pin its observable behavior. Physical revisions combine device, inode, size, and nanosecond timestamps for the preparation memo, stable-read retries, and publication checks. Historical public revisions add a SHA-256 fingerprint of sorted selected paths and their physical revisions; lock files and retained unselected generations do not contribute. ### Physical encoding diff --git a/packages/session/session-persistence-jsonl/README.zh.md b/packages/session/session-persistence-jsonl/README.zh.md index 3b265bf43f..71126dd909 100644 --- a/packages/session/session-persistence-jsonl/README.zh.md +++ b/packages/session/session-persistence-jsonl/README.zh.md @@ -79,7 +79,11 @@ kind: "package-reference" ### 读取日志 -`open(id, 'read'|'write')` 选择最高规范 generation。当前格式输入走普通快速路径。对于历史输入,只读 open 会单遍解码并迁移源、校验当前逻辑结果,然后在不发布后继的情况下返回。写 open 会在可用时复用按 revision 为键的 preparation,否则执行同一套 preparation,再按有界分片编码同目录临时文件、在 Worker Thread 中校验、复查源修订,并在返回前以不覆盖方式发布当前后继。源保持逐字节不变。如果源在 preparation 后发生变化,该次写 open 会失败,已经返回给读方的逻辑历史不会被替换;后续写 open 会针对新的 revision 重新执行 preparation。后端在 memo 化前冻结已解码的 event graph,并在此时将其标记为 `shared-frozen`;句柄读取和 slice 即使为空也保留该状态。只有尚未实体化的 pending 空日志报告 `detached`。`stat(id)` 与 `list()` 只选择并转换最高 generation 的 header,不读取事件行,也不启动迁移;快照携带所选文件的 `sizeBytes` 与尽力而为的 stat 派生修订号。选择 `compression: 'none'` 后,日志是外部读取方可直接消费的换行分隔文本;压缩默认值必须经后端读取。 +`open(id, 'read'|'write')` 选择最高规范 generation。当前格式输入走普通快速路径。对于历史输入,只读 open 会单遍解码并迁移源、校验当前逻辑结果,然后在不发布后继的情况下返回。写 open 会在可用时复用按 revision 为键的 preparation,否则执行同一套 preparation,再按有界分片编码同目录临时文件、在 Worker Thread 中校验、复查源修订,并在返回前以不覆盖方式发布当前后继。源保持逐字节不变。如果源在 preparation 后发生变化,该次写 open 会失败,已经返回给读方的逻辑历史不会被替换;后续写 open 会针对新的 revision 重新执行 preparation。后端在 memo 化前冻结已解码的 event graph,并在此时将其标记为 `shared-frozen`;每个嵌套对象和数组都会冻结,句柄读取和 slice 即使为空也保留该状态。只有尚未实体化的 pending 空日志报告 `detached`。`stat(id)` 与 `list()` 只选择并转换最高 generation 的 header,不读取事件行,也不启动迁移;快照携带所选文件的 `sizeBytes` 与尽力而为的修订号。当前格式修订号标识该文件;历史格式修订号还包含持久化根目录中所选文件的指纹,因此子日志变化会使缓存的逻辑事件失效。指纹只读取文件系统元数据;无关变化也会保守地使历史修订号失效。一次 `list()` 为其历史条目共用一个全库指纹。选择 `compression: 'none'` 后,日志是外部读取方可直接消费的换行分隔文本;压缩默认值必须经后端读取。 + +历史正文准备通过 [V3→V4](../session-format-v3-to-v4/README.zh.md) 补齐父目录:扫描 header,仅逐个解码直属子 Session,保留紧凑的 descriptor 证据及来源修订。在准备返回、复用和发布前重新检查成员集合与修订。来源变化会使准备缓存失效:只读打开自动重新准备一次,写打开则拒绝发布。诊断指出发生变化、新增、删除或无法读取的子日志路径。扫描中其他任何被选中的不支持代际或不可读 header 都会拒绝迁移,因为无法确认成员集合完整。普通列举仍跳过这些文件。子 descriptor 缺失、版本不受支持或存在多个时,只跳过该子 Session 的目录补填;已有父目录项和子日志仍可读取。恰好一个受支持的自身 descriptor 字段无效时,仍会报告格式不支持;子事件、JSON 记录或压缩数据畸形会在子日志路径报告损坏。文件系统错误与取消保留原始错误。当前 V4 打开跳过此扫描,并在暴露事件之前检查目录字段、唯一性及当前投递归属。 + +历史格式的 `stat` 与 `list` 修订号需要与根目录 Session 数量成正比的元数据工作。首次正文准备扫描所有所选 header 并解码直属子正文;复用准备缓存仍扫描成员集合并检查修订。只读访问从不发布升级,因此冷进程与被淘汰的准备缓存会重复这些工作。当前 V4 正文读取和修订号避开历史全库扫描。见[实测成本与诊断命令](../../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md#catalog-scan-measurements)。 ----- @@ -93,7 +97,7 @@ kind: "package-reference" ### 设计理念 -该后端拥有自己完整的存储运行时(`src/storage.ts`):`JsonlSessionHandle` 承载逐句柄修改链、带固定批处理窗口与 single-flight 排空的已路由实时事件缓冲、单调读取与幂等 close;一个 tracker 持有进程内单写者认领、teardown 清扫所遍历的打开句柄集合,以及后端自己的会话监听器所路由进的已创建但未实体化待定会话。历史正文读取共享每个 Session 唯一的一次 Decode/Migrate preparation,按 revision 为键的有界 memo 让紧接的观察到恢复交接复用该解析;backend 在 memo 化前只对每个 event graph 深度冻结一次,因此后续 handle read 无需复制或再次冻结。只有写 open 才发布准备好的后继。本包有意只暴露默认插件导出与配置类型——具体类不是具名导出,因此消费方只耦合 `ctx.sessionPersistence`,其可观察行为由共享 seam 测试套件(`runPersistenceContract`/`runLiveWritePathContract`)钉住。其变更令牌是尽力而为的文件修订值:device、inode、size 与纳秒时间戳标识一份日志,供 `stat`/`list`、在并发 append 撕裂读取时重试的稳定读取循环,以及发布前源检查使用。 +该后端拥有自己完整的存储运行时(`src/storage.ts`):`JsonlSessionHandle` 承载逐句柄修改链、带固定批处理窗口与 single-flight 排空的已路由实时事件缓冲、单调读取与幂等 close;一个 tracker 持有进程内单写者认领、teardown 清扫所遍历的打开句柄集合,以及后端自己的会话监听器所路由进的已创建但未实体化待定会话。历史正文读取共享每个 Session 唯一的一次 Decode/Migrate preparation,按 revision 为键的有界 memo 让紧接的观察到恢复交接复用该解析;backend 在 memo 化前只对每个 event graph 深度冻结一次,因此后续 handle read 无需复制或再次冻结。只有写 open 才发布准备好的后继。本包有意只暴露默认插件导出与配置类型——具体类不是具名导出,因此消费方只耦合 `ctx.sessionPersistence`,其可观察行为由共享 seam 测试套件(`runPersistenceContract`/`runLiveWritePathContract`)钉住。物理修订号组合 device、inode、size 与纳秒时间戳,供准备缓存、稳定读取重试及发布检查使用。历史格式的公开修订号还加入所选路径排序后及其物理修订号的 SHA-256 指纹;锁文件与保留但未被选中的代际不参与计算。 ### 物理编码 diff --git a/packages/session/session-persistence-jsonl/package.json b/packages/session/session-persistence-jsonl/package.json index 842ec06467..0966adcd58 100644 --- a/packages/session/session-persistence-jsonl/package.json +++ b/packages/session/session-persistence-jsonl/package.json @@ -36,10 +36,10 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session-format": "workspace:^", "@deepseek-ai/dsh-session-format-catalog": "workspace:^", - "@deepseek-ai/dsh-session-format-v2-to-v3": "workspace:^", + "@deepseek-ai/dsh-session-format-v3-to-v4": "workspace:^", "@deepseek-ai/node-addon-system": "workspace:^", - "koffi": "^3.1.0", - "@deepseek-ai/schemastery": "workspace:^" + "@deepseek-ai/schemastery": "workspace:^", + "koffi": "^3.1.0" }, "devDependencies": { "@deepseek-ai/dsh-session": "workspace:^", diff --git a/packages/session/session-persistence-jsonl/src/catalog-migration.ts b/packages/session/session-persistence-jsonl/src/catalog-migration.ts new file mode 100644 index 0000000000..77e3d8b43e --- /dev/null +++ b/packages/session/session-persistence-jsonl/src/catalog-migration.ts @@ -0,0 +1,82 @@ +/** Collect historical discovery facts without recursively preparing related current generations. */ + +import { stat } from 'node:fs/promises' +import { basename } from 'node:path' +import { historicalSessionFormatCatalog, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { historicalChildCatalogSource } from '@deepseek-ai/dsh-session-format-v3-to-v4' +import { SessionFormatUnsupportedError, SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' +import { SessionFormatError, SessionFormatUnsupportedMigrationError } from '@deepseek-ai/dsh-session-format' +import type { SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' +import type { SessionHeader, SessionId } from '@deepseek-ai/dsh-session' +import { parseGenerationLogFilename } from './format.ts' +import type { JsonlCompression } from './format.ts' +import { JsonlGenerationSourceChangedError, readDecodedJsonlSource } from './generation.ts' +import type { JsonlPhysicalIdentity } from './generation.ts' + +/** Per-parent supplemental facts and the source checks required before serving or publishing them. */ +interface PreparedCatalogFacts { + readonly facts: readonly SessionFormatJsonObject[] + /** @returns resolves while every decoded child still has the captured physical revision. */ + validate(): Promise +} + +/** + * Collect each related child's own descriptor through existing historical codecs. + * @param parentId - parent whose incoming migration consumes these facts. + * @param sources - header-indexed direct children in the selected source corpus. + * @param compression - configured source encoding. + * @param signal - cancellation forwarded through each source read. + * @returns compact facts; complete child event arrays are released after extraction. + */ +export async function prepareCatalogFacts( + parentId: SessionId, + sources: readonly { readonly header: SessionHeader; readonly path: string }[], + compression: JsonlCompression, + signal: AbortSignal, +): Promise { + const facts: SessionFormatJsonObject[] = [] + const witnesses: { path: string; identity: JsonlPhysicalIdentity }[] = [] + for (const source of sources) { + signal.throwIfAborted() + const version = parseGenerationLogFilename(basename(source.path), compression) + if (version === undefined) throw new SessionFormatUnsupportedMigrationError(`unrecognized historical child generation ${source.path}`) + let restored: Awaited> + try { + restored = await readDecodedJsonlSource(source.path, version, compression, { + createRestore: header => (version <= 3 ? historicalSessionFormatCatalog : sessionFormatCatalog).createRestore(header, { + recovery: 'recoverable', validation: 'current', + }), + }, signal) + } catch (error: unknown) { + if (error instanceof SessionFormatUnsupportedMigrationError) { + throw new SessionFormatUnsupportedError( + `child Session ${source.header.id}: ${error.message} (raw log: ${source.path})`, + { kind: 'jsonl', path: source.path }, + ) + } + if (error instanceof SessionFormatError) { + throw new SessionPersistenceCorruptionError(`child Session ${source.header.id}: ${error.message} (raw log: ${source.path})`, { cause: error }) + } + throw error + } + const header = restored.artifact.header + if (header.id !== source.header.id || header.createdAt !== source.header.createdAt + || header.parentSession !== parentId || header.origin !== 'subagent' + || ['cwd', 'isSeeded', 'delegationDepth', 'agentPreset'].some(key => header[key] !== source.header[key as keyof SessionHeader])) { + throw new JsonlGenerationSourceChangedError(source.path) + } + facts.push({ ...historicalChildCatalogSource(restored.artifact), sourcePath: source.path }) + witnesses.push({ path: source.path, identity: restored.identity }) + } + return { + facts, + async validate() { + for (const witness of witnesses) { + const current = await stat(witness.path, { bigint: true }) + if (current.dev !== witness.identity.dev || current.ino !== witness.identity.ino + || current.size !== witness.identity.size || current.mtimeNs !== witness.identity.mtimeNs + || current.ctimeNs !== witness.identity.ctimeNs) throw new JsonlGenerationSourceChangedError(witness.path) + } + }, + } +} diff --git a/packages/session/session-persistence-jsonl/src/format.ts b/packages/session/session-persistence-jsonl/src/format.ts index 4129207ece..781c5d83c3 100644 --- a/packages/session/session-persistence-jsonl/src/format.ts +++ b/packages/session/session-persistence-jsonl/src/format.ts @@ -11,6 +11,7 @@ import { isAbsolute, join } from 'node:path' import { SESSION_FORMAT_VERSION, + KNOWN_SESSION_EVENT_TYPES, SessionLogOffset, } from '@deepseek-ai/dsh-session' import type { @@ -23,7 +24,7 @@ import { parseSessionFormatLogFilename, sessionFormatLogFilename, SessionFormatU import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' import type { SessionFormatRecovery, SessionFormatRestore } from '@deepseek-ai/dsh-session-format' import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' -import { assertV3RowAdmission } from '@deepseek-ai/dsh-session-format-v2-to-v3' +import { assertV4RowAdmission, assertReleasedV4Relationships } from '@deepseek-ai/dsh-session-format-v3-to-v4' import { SessionFormatUnsupportedError, sessionFormatVersionRefusal, @@ -464,6 +465,7 @@ export class SessionLogScanner { finish(): SessionLogScan { this.finished = true const artifact = this.restore.finish() + assertReleasedV4Relationships(artifact, KNOWN_SESSION_EVENT_TYPES) return { meta: this.meta, inheritedEventCount: SessionLogOffset(artifact.inheritedEventCount), @@ -488,7 +490,7 @@ export class SessionLogScanner { // This scanner accepts only current-generation files. Owned structural refusal must // precede its recoverable-tail suppression, independently of the strict decoder state. try { - assertV3RowAdmission(decoded) + assertV4RowAdmission(decoded, KNOWN_SESSION_EVENT_TYPES) } catch (error: unknown) { if (error instanceof SessionFormatUnsupportedMigrationError) throw new SessionFormatUnsupportedError(error.message) throw error @@ -502,7 +504,7 @@ export class SessionLogScanner { try { this.restore.decodeRow(decoded) } catch (error: unknown) { - // Unsupported V3 rows have already been refused before recovery. + // Unsupported current-format rows have already been refused before recovery. /* v8 ignore next -- every production Session format decoder rejects with Error. */ const detail = error instanceof Error ? error.message : String(error) const issue = new Error(`corrupt session log: invalid committed event at line ${this.eventLine}: ${detail}`, { diff --git a/packages/session/session-persistence-jsonl/src/generation.ts b/packages/session/session-persistence-jsonl/src/generation.ts index 1e5ded6771..ff01e9a038 100644 --- a/packages/session/session-persistence-jsonl/src/generation.ts +++ b/packages/session/session-persistence-jsonl/src/generation.ts @@ -28,6 +28,7 @@ import { constants, createZstdCompress } from 'node:zlib' import { Session } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import { BlockAssembler, expandAssistantStream } from '@deepseek-ai/dsh-llm' +import { SessionFormatError } from '@deepseek-ai/dsh-session-format' import type { SessionFormatArtifact, SessionFormatJsonValue, @@ -68,6 +69,8 @@ export interface JsonlGenerationFormatAdapter { /** Inputs for preparing one historical generation and publishing its current successor later. */ export interface PrepareJsonlMigrationOptions { + /** Revalidate related source facts before preparation returns and immediately before publication. */ + readonly validateRelatedSources?: () => Promise /** Immutable generation selected by the backend resolver. */ readonly sourcePath: string /** Version selected from the source filename and independently checked against its header. */ @@ -372,7 +375,7 @@ interface StartedMigrationStream { async function startMigrationStream( headerRecord: Buffer, sourceVersion: number, - format: JsonlGenerationFormatAdapter, + format: Pick, validateHistoricalHeader?: PrepareJsonlMigrationOptions['validateHistoricalHeader'], ): Promise { const value = parseJson(headerRecord.subarray(0, -1).toString('utf8'), 'header line') @@ -409,7 +412,7 @@ async function decodeStreamingMigration( bytes: Buffer, compression: JsonlCompression, sourceVersion: number, - format: JsonlGenerationFormatAdapter, + format: Pick, validateHistoricalHeader: PrepareJsonlMigrationOptions['validateHistoricalHeader'], signal?: AbortSignal, ): Promise { @@ -900,6 +903,7 @@ async function publishPreparedMigration( throw new Error('staged session generation changed during verification') } await internals.barrier('before-source-check', 1) + await options.validateRelatedSources?.() const beforePublish = await internals.fs.stat(sourcePath) if (identity(beforePublish) !== identity(sourceIdentity)) { throw new JsonlGenerationSourceChangedError(sourcePath) @@ -974,6 +978,7 @@ async function prepareMigration( if (artifact.header.version !== format.currentVersion) { throw new Error(`format migration returned v${artifact.header.version}, expected v${format.currentVersion}`) } + await options.validateRelatedSources?.() const sourceIdentity = source.identity let publication: Promise | undefined return { @@ -1024,3 +1029,31 @@ export function createJsonlGenerationRuntime( } const defaultGenerationRuntime = createJsonlGenerationRuntime() + +/** + * Read one stable source through the shared streaming parser without publishing a generation. + * @param path - selected source generation path. + * @param version - physical source version identified by its filename. + * @param compression - source encoding. + * @param format - codec/restore factory, independent of current-generation publication. + * @param signal - cancellation observed during source reads and decode yields. + * @returns decoded artifact and physical source identity for later revalidation. + * @throws SessionFormatError for physical decoding failures; storage, cancellation, and unsupported migration errors retain their category. + */ +export async function readDecodedJsonlSource( + path: string, + version: number, + compression: JsonlCompression, + format: Pick, + signal?: AbortSignal, +): Promise<{ artifact: SessionFormatArtifact; identity: JsonlPhysicalIdentity }> { + const source = await readStableJsonlFile(path, signal) + let artifact: SessionFormatArtifact + try { + artifact = await decodeStreamingMigration(source.bytes, compression, version, format, undefined, signal) + } catch (error: unknown) { + if (signal?.aborted || error instanceof SessionFormatError) throw error + throw new SessionFormatError(String(error), { cause: error }) + } + return { artifact, identity: source.identity } +} diff --git a/packages/session/session-persistence-jsonl/src/index.ts b/packages/session/session-persistence-jsonl/src/index.ts index ba4f8996f0..6e7e7b5628 100644 --- a/packages/session/session-persistence-jsonl/src/index.ts +++ b/packages/session/session-persistence-jsonl/src/index.ts @@ -9,6 +9,7 @@ import { Context } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' import { + createSessionFormatCatalogWithChildren, SessionFormatUnsupportedMigrationError, sessionFormatCatalog, } from '@deepseek-ai/dsh-session-format-catalog' @@ -17,7 +18,7 @@ import { open, mkdir, readdir, realpath, link, rm, stat, truncate } from 'node:f import { dirname, join, resolve } from 'node:path' import { performance } from 'node:perf_hooks' import { scheduler } from 'node:timers/promises' -import { randomBytes } from 'node:crypto' +import { createHash, randomBytes } from 'node:crypto' import { SessionPersistence, SessionPersistenceRevision, SessionFormatUnsupportedError, SessionPersistenceCorruptionError, @@ -44,6 +45,7 @@ import { } from './zstd.ts' import { ensureDurableDirectoryWin32, publishNewFileWin32 } from './win32.ts' import { verifyCurrentGenerationInWorker } from './migration-verifier.ts' +import { prepareCatalogFacts } from './catalog-migration.ts' import { JsonlGenerationSourceChangedError, JsonlGenerationUnsupportedMigrationError, @@ -122,6 +124,7 @@ interface CurrentStoredLog extends StoredLogBase { /** A migrated historical generation retained until an explicit write open publishes it. */ interface PreparedStoredLog extends StoredLogBase { readonly status: 'prepared' + readonly validateRelatedSources: () => Promise readonly publication: { readonly source: ResolvedJsonlGeneration readonly value: PreparedJsonlMigration @@ -131,7 +134,7 @@ interface PreparedStoredLog extends StoredLogBase { /** A validated logical log, either durable current state or prepared historical state. */ type StoredLog = CurrentStoredLog | PreparedStoredLog -/** Deep-freeze one acyclic stored JSON event without recursive calls. */ +/** Deep-freeze acyclic stored JSON; its arrays contain only indexed JSON values. */ function freezeStoredEvent(event: SessionEvent): void { const pending: object[] = [event] while (pending.length > 0) { @@ -139,9 +142,16 @@ function freezeStoredEvent(event: SessionEvent): void { // oxlint-disable-next-line typescript/no-non-null-assertion const current = pending.pop()! Object.freeze(current) - for (const key in current) { - const child = (current as Record)[key] - if (child !== null && typeof child === 'object') pending.push(child) + if (Array.isArray(current)) { + for (let index = 0; index < current.length; index += 1) { + const child: unknown = current[index] + if (child !== null && typeof child === 'object') pending.push(child) + } + } else { + for (const key in current) { + const child = (current as Record)[key] + if (child !== null && typeof child === 'object') pending.push(child) + } } } } @@ -245,7 +255,7 @@ class JsonlSessionPersistence extends SessionPersistence { private compression: JsonlCompression private rootEncodingCheck: Promise | undefined private readonly tracker = new JsonlBackendTracker(this.name) - private readonly generationFormat: JsonlGenerationFormatAdapter + private readonly generationFormat: Omit /** * Bounded LRU of parsed, validated stored logs keyed by session id and * guarded by the stat-derived revision, so an immediate cold-read handoff @@ -271,10 +281,6 @@ class JsonlSessionPersistence extends SessionPersistence { this.compression = config.compression ?? DEFAULT_COMPRESSION this.generationFormat = { currentVersion: sessionFormatCatalog.currentVersion, - createRestore: header => sessionFormatCatalog.createRestore(header, { - recovery: 'recoverable', - validation: 'transformed', - }), encodeHeader: (header, inheritedEventCount) => sessionFormatCatalog.encodeCurrentHeader(header, inheritedEventCount), encodeEvent: event => sessionFormatCatalog.encodeCurrentEvent(event), @@ -342,7 +348,13 @@ class JsonlSessionPersistence extends SessionPersistence { if (pending !== undefined) { return this.tracker.adopt(new JsonlSessionHandle(this, id, pending.header, 'read', { cursor: 0, materialized: false, inheritedEventCount: pending.inheritedEventCount })) } - const stored = await this.requireStoredLog(id, options?.signal) + let stored: StoredLog + try { + stored = await this.requireStoredLog(id, options?.signal) + } catch (error: unknown) { + if (!(error instanceof JsonlGenerationSourceChangedError)) throw error + stored = await this.requireStoredLog(id, options?.signal) + } let state: StorageHandleState if (stored.status === 'prepared') { state = { @@ -442,7 +454,9 @@ class JsonlSessionPersistence extends SessionPersistence { options?.signal?.throwIfAborted() return { header, - revision: fileRevision(identity), + revision: selected.sourceVersion < SESSION_FORMAT_VERSION + ? SessionPersistenceRevision(`${fileRevision(identity)}:${await this.historicalCorpusRevision(options?.signal)}`) + : fileRevision(identity), sizeBytes: Number(identity.size), } } catch (error: unknown) { @@ -466,7 +480,10 @@ class JsonlSessionPersistence extends SessionPersistence { // append lands mid-scan is then still in this snapshot (its artifact may // predate the scan), so create-to-list visibility never has a hole. const pending = [...this.tracker.pendingEntries()] - for (const artifact of await this.listArtifacts(signal)) { + const artifacts = await this.listArtifacts(signal) + const corpusRevision = artifacts.some(artifact => artifact.sourceVersion < SESSION_FORMAT_VERSION) + ? await this.historicalCorpusRevision(signal) : undefined + for (const artifact of artifacts) { signal?.throwIfAborted() try { const identity = await stat(artifact.path, { bigint: true }) @@ -474,7 +491,9 @@ class JsonlSessionPersistence extends SessionPersistence { listed.add(artifact.header.id) snapshots.push({ header: artifact.header, - revision: fileRevision(identity), + revision: artifact.sourceVersion < SESSION_FORMAT_VERSION + ? SessionPersistenceRevision(`${fileRevision(identity)}:${corpusRevision}`) + : fileRevision(identity), sizeBytes: Number(identity.size), }) } catch (error: unknown) { @@ -567,6 +586,12 @@ class JsonlSessionPersistence extends SessionPersistence { signal.throwIfAborted() const memoized = this.coldLogMemo.get(id) if (memoized?.status === 'prepared' && memoized.revision === sourceRevision) { + try { + await memoized.validateRelatedSources() + } catch (error: unknown) { + this.coldLogMemo.delete(id) + throw this.generationFailure(id, selected, error) + } this.coldLogMemo.delete(id) this.coldLogMemo.set(id, memoized) return memoized @@ -602,13 +627,33 @@ class JsonlSessionPersistence extends SessionPersistence { signal: AbortSignal, ): Promise { let prepared: Awaited> + let validateRelatedSources: () => Promise try { + const children = async () => (await this.listArtifacts(signal, selected.sourcePath)) + .filter(source => source.header.origin === 'subagent' && source.header.parentSession === id) + const sources = await children() + const related = await prepareCatalogFacts(id, sources, this.compression, signal) + const membership = sources.map(source => source.path).sort() + validateRelatedSources = async () => { + const current = (await children()).map(source => source.path).sort() + const before = new Set(membership) + const after = new Set(current) + const changed = current.find(path => !before.has(path)) ?? membership.find(path => !after.has(path)) + if (changed !== undefined) throw new JsonlGenerationSourceChangedError(changed) + await related.validate() + } prepared = await prepareJsonlMigration({ sourcePath: selected.sourcePath, sourceVersion: selected.sourceVersion, currentPath: selected.currentPath, compression: this.compression, - format: this.generationFormat, + format: { + ...this.generationFormat, + createRestore: header => createSessionFormatCatalogWithChildren(related.facts).createRestore(header, { + recovery: 'recoverable', validation: 'transformed', + }), + }, + validateRelatedSources, verifyCurrentFile: verifyCurrentGenerationInWorker, validateHistoricalHeader: headerValue => this.validateSourceIdentity( selected, @@ -627,6 +672,7 @@ class JsonlSessionPersistence extends SessionPersistence { validateStoredEvents(meta, events, { kind: 'jsonl', path: selected.sourcePath }) const stored: PreparedStoredLog = { status: 'prepared', + validateRelatedSources, meta, ...freezeStoredEvents(events), tornTruncateTo: undefined, @@ -972,35 +1018,77 @@ class JsonlSessionPersistence extends SessionPersistence { } } - private async listArtifacts(signal?: AbortSignal): Promise> { - signal?.throwIfAborted() - await this.ensureRootEncoding() - signal?.throwIfAborted() - const artifacts: Array<{ header: SessionHeader; path: string }> = [] - const ids = new Set() + /** Enumerate selected physical generations without interpreting their headers or bodies. */ + private async listGenerations(signal?: AbortSignal): Promise { + const sources: ResolvedJsonlGeneration[] = [] for (const project of await this.listProjectDirs(signal)) { - signal?.throwIfAborted() for (const dir of await this.listSessionDirs(project, signal)) { signal?.throwIfAborted() const selected = await this.resolveGenerationInDirectory(dir, signal) - if (selected === undefined) continue - let header: SessionHeader | undefined - try { - header = await this.readGenerationHeader(selected, undefined, signal) - } catch (error: unknown) { - // Listing skips a foreign format while opening its id still refuses - // with the selected physical location. - if (error instanceof SessionFormatUnsupportedError) continue - throw error - } - if (header === undefined) continue - if (ids.has(header.id)) { - throw new Error(`duplicate JSONL session id "${header.id}" appears in multiple project directories`) - } - ids.add(header.id) - artifacts.push({ header, path: selected.sourcePath }) + if (selected !== undefined) sources.push(selected) } } + return sources + } + + /** Historical logical events depend on the corpus, including members with unreadable headers. */ + private async historicalCorpusRevision(signal?: AbortSignal): Promise { + const paths = (await this.listGenerations(signal)).map(source => source.sourcePath).sort() + const hash = createHash('sha256') + for (const path of paths) { + signal?.throwIfAborted() + let revision: string + try { + revision = fileRevision(await stat(path, { bigint: true })) + } catch (error: unknown) { + if (!isENOENT(error)) throw error + revision = 'missing' + } + hash.update(JSON.stringify([path, revision])) + } + signal?.throwIfAborted() + return hash.digest('hex') + } + + private async listArtifacts( + signal?: AbortSignal, + migrationSource?: string, + ): Promise> { + signal?.throwIfAborted() + await this.ensureRootEncoding() + signal?.throwIfAborted() + const artifacts: Array<{ header: SessionHeader; path: string; sourceVersion: number }> = [] + const ids = new Set() + for (const selected of await this.listGenerations(signal)) { + signal?.throwIfAborted() + if (migrationSource !== undefined && selected.sourceVersion > SESSION_FORMAT_VERSION) { + throw new SessionFormatUnsupportedError( + `catalog migration cannot inspect Session format v${selected.sourceVersion}; upgrade the harness (raw log: ${selected.sourcePath})`, + { kind: 'jsonl', path: selected.sourcePath }, + ) + } + let header: SessionHeader | undefined + try { + header = await this.readGenerationHeader(selected, undefined, signal) + } catch (error: unknown) { + if (error instanceof SessionFormatUnsupportedError && migrationSource === undefined) continue + throw error + } + if (header === undefined) { + if (migrationSource !== undefined && selected.sourcePath !== migrationSource) { + throw new SessionFormatUnsupportedError( + `cannot establish complete catalog membership from an unreadable Session header (raw log: ${selected.sourcePath})`, + { kind: 'jsonl', path: selected.sourcePath }, + ) + } + continue + } + if (ids.has(header.id)) { + throw new Error(`duplicate JSONL session id "${header.id}" appears in multiple project directories`) + } + ids.add(header.id) + artifacts.push({ header, path: selected.sourcePath, sourceVersion: selected.sourceVersion }) + } signal?.throwIfAborted() return artifacts } diff --git a/packages/session/session-persistence-jsonl/tests/built-migration-worker.e2e.ts b/packages/session/session-persistence-jsonl/tests/built-migration-worker.e2e.ts index a75a9496ef..9d130a40a9 100644 --- a/packages/session/session-persistence-jsonl/tests/built-migration-worker.e2e.ts +++ b/packages/session/session-persistence-jsonl/tests/built-migration-worker.e2e.ts @@ -2,6 +2,7 @@ import { existsSync } from 'node:fs' import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { execa } from 'execa' +import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session' import { describe, expect, it } from 'vitest' const packageRoot = fileURLToPath(new URL('..', import.meta.url)) @@ -16,6 +17,7 @@ describe.skipIf(!built)('built migration verifier (plain node)', () => { import { join } from 'node:path' import { Worker } from 'node:worker_threads' import { Context } from '@deepseek-ai/cordis' + import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' const root = await mkdtemp(join(tmpdir(), 'dsh-built-migration-')) @@ -31,7 +33,7 @@ describe.skipIf(!built)('built migration verifier (plain node)', () => { const handle = await ctx.sessionPersistence.open(id, 'write') await handle.close() await ctx.sessionPersistence.flush() - const currentPath = join(directory, 'session.v3.jsonl') + const currentPath = join(directory, 'session.v' + SESSION_FORMAT_VERSION + '.jsonl') const header = JSON.parse((await readFile(currentPath, 'utf8')).trim()) await mkdir(join(root, 'lib')) await copyFile('package.json', join(root, 'package.json')) @@ -71,7 +73,7 @@ describe.skipIf(!built)('built migration verifier (plain node)', () => { expect(exitCode, `stderr:\n${stderr}`).toBe(0) expect(JSON.parse(stdout.trim())).toEqual({ - id: 'built-migration-worker', version: 3, verified: true, refused: false, + id: 'built-migration-worker', version: SESSION_FORMAT_VERSION, verified: true, refused: false, refusal: 'current session generation contains 0 events, expected 1', }) }) diff --git a/packages/session/session-persistence-jsonl/tests/catalog-migration.perf.ts b/packages/session/session-persistence-jsonl/tests/catalog-migration.perf.ts new file mode 100644 index 0000000000..a866354449 --- /dev/null +++ b/packages/session/session-persistence-jsonl/tests/catalog-migration.perf.ts @@ -0,0 +1,77 @@ +/** Threshold-free, built-runtime measurements of historical catalog reads as the corpus grows. */ + +import { Context } from '@deepseek-ai/cordis' +import { SessionId } from '@deepseek-ai/dsh-session' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { spawnSync } from 'node:child_process' +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { performance } from 'node:perf_hooks' +import { fileURLToPath } from 'node:url' + +const CHILDREN = 4 +const CHILD_EVENTS = 1_000 +const SAMPLES = 3 + +async function measure(unrelated: number) { + const root = await mkdtemp(join(tmpdir(), 'dsh-catalog-perf-')) + const ctx = new Context() + try { + for (let i = 0; i < unrelated + CHILDREN + 1; i++) { + const id = i === 0 ? 'parent' : `session-${i}` + const child = i > 0 && i <= CHILDREN + const directory = join(root, '_no-cwd', id) + await mkdir(directory, { recursive: true }) + const header = { type: 'session', version: 3, id, createdAt: i + 1, isSeeded: false, delegationDepth: child ? 1 : 0, + ...(child ? { origin: 'subagent', parentSession: 'parent' } : {}) } + const events = child ? [ + { type: 'subagent/descriptor', seq: 0, time: 1, data: { version: 3, mode: 'one-shot', provider: 'spawn' } }, + ...Array.from({ length: CHILD_EVENTS - 1 }, (_, seq) => ({ + type: 'feedback/record', seq: seq + 1, time: 2, data: { text: 'Synthetic migration observation. '.repeat(4) }, + })), + ] : [] + await writeFile(join(directory, 'session.v3.jsonl'), [header, ...events].map(row => JSON.stringify(row) + '\n').join('')) + } + await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' }) + const parent = SessionId('parent') + const timed = async (operation: () => Promise): Promise => { + const start = performance.now() + await operation() + return performance.now() - start + } + const read = async (): Promise => { + const handle = await ctx.sessionPersistence.open(parent, 'read') + try { await handle.read() } finally { await handle.close() } + } + const statMs = await timed(() => ctx.sessionPersistence.stat(parent)) + const coldReadMs = await timed(read) + const memoReadMs = await timed(read) + const publishMs = await timed(async () => { + const handle = await ctx.sessionPersistence.open(parent, 'write') + await handle.close() + }) + const currentReadMs = await timed(read) + return { unrelated, children: CHILDREN, childEvents: CHILD_EVENTS, statMs, coldReadMs, memoReadMs, publishMs, currentReadMs } + } finally { + await ctx.fiber.dispose() + await rm(root, { recursive: true, force: true }) + } +} + +if (process.argv[2] === '--sample') { + process.stdout.write(JSON.stringify(await measure(Number(process.argv[3]))) + '\n') +} else { + const samples = [] + for (const size of [0, 100, 1_000]) { + for (let sample = 0; sample < SAMPLES; sample++) { + const result = spawnSync(process.execPath, [fileURLToPath(import.meta.url), '--sample', String(size)], { + encoding: 'utf8', timeout: 60_000, + }) + if (result.error !== undefined) throw result.error + if (result.signal !== null || result.status !== 0) throw new Error(`measurement failed: ${result.signal ?? result.status}: ${result.stderr}`) + samples.push(JSON.parse(result.stdout) as Record) + } + } + process.stdout.write(JSON.stringify({ node: process.version, platform: process.platform, arch: process.arch, samples }, null, 2) + '\n') +} diff --git a/packages/session/session-persistence-jsonl/tests/catalog-migration.spec.ts b/packages/session/session-persistence-jsonl/tests/catalog-migration.spec.ts new file mode 100644 index 0000000000..af86cdbfe6 --- /dev/null +++ b/packages/session/session-persistence-jsonl/tests/catalog-migration.spec.ts @@ -0,0 +1,380 @@ +import { Context } from '@deepseek-ai/cordis' +import { SessionId, type SessionHeader } from '@deepseek-ai/dsh-session' +import { SessionFormatUnsupportedError, SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { afterEach, describe, expect, it } from 'vitest' +import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { generationLogPath } from '../src/format.ts' +import { prepareCatalogFacts } from '../src/catalog-migration.ts' +import { compressZstdFrame } from '../src/zstd.ts' + +const roots: string[] = [] +const contexts: Context[] = [] + +afterEach(async () => { + await Promise.all(contexts.splice(0).map(ctx => ctx.fiber.dispose())) + await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true }))) +}) + +describe.each(['none', 'zstd'] as const)('historical catalog publication (%s)', (compression) => { + async function fixture() { + const root = await mkdtemp(join(tmpdir(), 'dsh-catalog-migration-')) + roots.push(root) + const ctx = new Context() + contexts.push(ctx) + await ctx.plugin(JsonlSessionPersistence, { root, compression }) + const parent = SessionId('parent') + const header = { type: 'session', version: 3, id: parent, createdAt: 1, isSeeded: false, delegationDepth: 0 } + async function write(id: string, events: unknown[], child = false, version = 3) { + const path = generationLogPath(root, undefined, SessionId(id), version, compression) + await mkdir(dirname(path), { recursive: true }) + const meta: Record = { ...header, id, version, ...(child ? { origin: 'subagent', parentSession: parent, createdAt: 2, delegationDepth: 1 } : {}) } + if (version < 2) delete meta['isSeeded'] + const first = JSON.stringify(meta) + '\n' + const body = events.map(row => JSON.stringify(row) + '\n').join('') + await writeFile(path, compression === 'none' ? first + body + : Buffer.concat([await compressZstdFrame(first), ...(body.length === 0 ? [] : [await compressZstdFrame(body)])])) + return path + } + await write(parent, []) + const descriptor = { type: 'subagent/descriptor', seq: 0, time: 2, data: { version: 3, mode: 'continuable', provider: 'spawn', label: 'old child' } } + async function read() { + const handle = await ctx.sessionPersistence.open(parent, 'read') + try { return (await handle.read()).events } finally { await handle.close() } + } + return { root, ctx, parent, header, descriptor, write, read } + } + + it.each(['read', 'write'] as const)('refuses foreign native V4 delivery through %s access', async (access) => { + const f = await fixture() + await f.write(f.parent, [ + { type: 'feedback/record', seq: 0, time: 1, data: {} }, + { type: 'session-log-deepseek/delivery-accepted', seq: 1, time: 2, + data: { sessionId: 'other', sessionFormatVersion: 4, throughSeq: 0 } }, + ], false, 4) + await expect(f.ctx.sessionPersistence.open(f.parent, access)).rejects.toThrow('wrong Session') + }) + + it('does not publish incomplete membership after a child header becomes unreadable', async () => { + const f = await fixture() + const path = await f.write('child', [], true) + const broken = '{broken header\n' + await writeFile(path, compression === 'none' ? broken : await compressZstdFrame(broken)) + await expect(f.read()).rejects.toThrow(path) + await expect(f.ctx.sessionPersistence.open(f.parent, 'write')).rejects.toThrow(path) + expect((await readdir(dirname(generationLogPath(f.root, undefined, f.parent, 3, compression)))).filter(name => name !== 'session.lock')) + .toEqual([compression === 'none' ? 'session.v3.jsonl' : 'session.v3.jsonl.zstd']) + }) + + it('invalidates lightweight revisions on child membership and contents while retaining stable tokens', async () => { + const f = await fixture() + const revision = async () => (await f.ctx.sessionPersistence.stat(f.parent))!.revision + const first = await revision() + expect(await revision()).toBe(first) + await f.write('child', [f.descriptor], true) + const added = await revision() + expect(added).not.toBe(first) + expect((await f.ctx.sessionPersistence.list()).find(row => row.header.id === f.parent)?.revision).toBe(added) + await f.write('child', [f.descriptor, { type: 'feedback/record', seq: 1, time: 3, data: {} }], true) + expect(await revision()).not.toBe(added) + }) + + it('reports malformed native catalog data without migration terminology', async () => { + const f = await fixture() + await f.write(f.parent, [{ type: 'subagent/catalog', seq: 0, time: 1, + data: { version: 0, childId: 'child', childCreatedAt: 2, mode: 'invalid' } }], false, 4) + const error = await f.read().catch((error: unknown) => error) + expect(error).toBeInstanceOf(SessionPersistenceCorruptionError) + expect((error as Error).message).not.toContain('migration requires') + }) + + it('keeps current revisions independent of unrelated historical logs and write ownership', async () => { + const f = await fixture() + await f.write(f.parent, [], false, 4) + const first = (await f.ctx.sessionPersistence.stat(f.parent))!.revision + await f.write('child', [f.descriptor], true) + expect((await f.ctx.sessionPersistence.stat(f.parent))!.revision).toBe(first) + expect((await f.ctx.sessionPersistence.list()).find(row => row.header.id === f.parent)?.revision).toBe(first) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + expect((await f.ctx.sessionPersistence.stat(f.parent))!.revision).toBe(first) + }) + + it('invalidates historical revisions when selected children disappear or gain an opaque successor', async () => { + const f = await fixture() + const path = await f.write('child', [f.descriptor], true) + const first = (await f.ctx.sessionPersistence.stat(f.parent))!.revision + await rm(path) + const removed = (await f.ctx.sessionPersistence.stat(f.parent))!.revision + expect(removed).not.toBe(first) + await f.write('child', [], true, 5) + expect((await f.ctx.sessionPersistence.stat(f.parent))!.revision).not.toBe(removed) + expect((await f.ctx.sessionPersistence.list()).find(row => row.header.id === f.parent)?.revision).not.toBe(removed) + }) + + it('reports a corrupt child body at the child location', async () => { + const f = await fixture() + const catalog = { type: 'subagent/catalog', seq: 0, time: 1, + data: { version: 0, childId: 'grandchild', childCreatedAt: 3, mode: 'one-shot' } } + const path = await f.write('child', [catalog, { ...catalog, seq: 1 }], true, 4) + await expect(f.read()).rejects.toBeInstanceOf(SessionPersistenceCorruptionError) + await expect(f.read()).rejects.toThrow(path) + }) + + it.each(['read', 'write'] as const)('locates physical child JSON corruption during %s access', async (access) => { + const f = await fixture() + const childPath = await f.write('child', [], true) + const first = JSON.stringify({ ...f.header, id: 'child', origin: 'subagent', parentSession: f.parent, delegationDepth: 1 }) + '\n' + // A sealed turn makes the malformed row corruption rather than a recoverable tail. + const body = '{broken\n' + JSON.stringify({ type: 'turn/end', seq: 1, time: 2, + data: { turn: 1, reason: { kind: 'completed' } } }) + '\n' + await writeFile(childPath, compression === 'none' ? first + body + : Buffer.concat([await compressZstdFrame(first), await compressZstdFrame(body)])) + const parentPath = generationLogPath(f.root, undefined, f.parent, 3, compression) + const original = await Promise.all([readFile(parentPath), readFile(childPath)]) + const error: unknown = await f.ctx.sessionPersistence.open(f.parent, access).catch((error: unknown) => error) + expect(error).toBeInstanceOf(SessionPersistenceCorruptionError) + expect((error as Error).message).toContain(childPath) + expect((error as Error).message).not.toContain(parentPath) + expect((error as Error).message).toContain('row 1 is not valid JSON') + expect(await Promise.all([readFile(parentPath), readFile(childPath)])).toEqual(original) + expect((await readdir(dirname(parentPath))).filter(name => name !== 'session.lock')) + .toEqual([compression === 'none' ? 'session.v3.jsonl' : 'session.v3.jsonl.zstd']) + }) + + it('preserves opaque inherited catalogs through read preparation and write publication', async () => { + const f = await fixture() + const parentPath = generationLogPath(f.root, undefined, f.parent, 3, compression) + const first = JSON.stringify({ ...f.header, isSeeded: true, parentSession: 'ancestor' }) + '\n' + const events = [ + { type: 'subagent/catalog', seq: 0, time: 1, data: { version: 99 } }, + { type: 'session/end-seed', seq: 1, time: 2, data: { inherited: true } }, + { type: 'subagent/catalog', seq: 2, time: 3, data: null }, + { type: 'session/end-seed', seq: 3, time: 4, data: { inherited: true } }, + ] + const body = events.map(event => JSON.stringify(event) + '\n').join('') + await writeFile(parentPath, compression === 'none' ? first + body + : Buffer.concat([await compressZstdFrame(first), await compressZstdFrame(body)])) + const original = await readFile(parentPath) + expect(await f.read()).toEqual(events) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + try { expect((await writer.read()).events).toEqual(events) } finally { await writer.close() } + expect(await f.read()).toEqual(events) + expect(await readFile(parentPath)).toEqual(original) + }) + + it.skipIf(compression !== 'zstd')('locates invalid compressed child frames at the child path', async () => { + const f = await fixture() + const childPath = await f.write('child', [], true) + await writeFile(childPath, Buffer.concat([await readFile(childPath), Buffer.alloc(8)])) + const error: unknown = await f.read().catch((error: unknown) => error) + expect(error).toBeInstanceOf(SessionPersistenceCorruptionError) + expect((error as Error).message).toContain(childPath) + }) + + it('keeps a complete parent catalog when a published child never writes a descriptor', async () => { + const f = await fixture() + const catalog = { type: 'subagent/catalog', seq: 0, time: 2, + data: { version: 0, childId: 'child', childCreatedAt: 2, mode: 'one-shot', label: 'failed startup' } } + const parentPath = await f.write(f.parent, [catalog]) + const childPath = await f.write('child', [], true) + const original = await Promise.all([readFile(parentPath), readFile(childPath)]) + expect(await f.read()).toEqual([catalog]) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + expect(await f.read()).toEqual([catalog]) + expect(await Promise.all([readFile(parentPath), readFile(childPath)])).toEqual(original) + }) + + it.each([1, 2, 3])('backfills a missing catalog from descriptor v%i', async (version) => { + const f = await fixture() + const data = version === 1 ? { version, provider: 'spawn', label: 'old child' } + : { ...f.descriptor.data, version } + await f.write('child', [{ ...f.descriptor, data }], true) + expect(await f.read()).toMatchObject([{ type: 'subagent/catalog', data: { + childId: 'child', childCreatedAt: 2, mode: 'continuable', label: 'old child', + } }]) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + }) + + it.each(['missing', 'unknown', 'multiple'] as const)('publishes the parent without invented %s child discovery information', async (kind) => { + const f = await fixture() + const events = kind === 'missing' ? [] : kind === 'unknown' + ? [{ ...f.descriptor, data: { version: 99, extension: { retained: true } } }] + : [f.descriptor, { ...f.descriptor, seq: 1, data: { ...f.descriptor.data, label: 'second descriptor' } }] + const childPath = await f.write('child', events, true) + const parentPath = generationLogPath(f.root, undefined, f.parent, 3, compression) + const original = await Promise.all([readFile(parentPath), readFile(childPath)]) + expect(await f.read()).toEqual([]) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + try { expect((await writer.read()).events).toEqual([]) } finally { await writer.close() } + expect(await f.read()).toEqual([]) + const child = await f.ctx.sessionPersistence.open(SessionId('child'), 'read') + try { expect((await child.read()).events).toEqual(events) } finally { await child.close() } + expect(await Promise.all([readFile(parentPath), readFile(childPath)])).toEqual(original) + expect((await readdir(dirname(parentPath))).filter(name => name !== 'session.lock').sort()) + .toEqual(compression === 'none' ? ['session.v3.jsonl', 'session.v4.jsonl'] : ['session.v3.jsonl.zstd', 'session.v4.jsonl.zstd']) + }) + + it.each([false, true])('refuses an opaque future generation before publishing membership (prepared=%s)', async (prepared) => { + const f = await fixture() + await f.write('child', [f.descriptor], true) + if (prepared) expect(await f.read()).toHaveLength(1) + await f.write('child', [], true, 5) + await expect(f.ctx.sessionPersistence.open(f.parent, 'write')).rejects.toBeInstanceOf(SessionFormatUnsupportedError) + expect((await readdir(dirname(generationLogPath(f.root, undefined, f.parent, 3, compression)))).filter(name => name !== 'session.lock')) + .toEqual([compression === 'none' ? 'session.v3.jsonl' : 'session.v3.jsonl.zstd']) + }) + + it('requires a readable corpus even when an unknown header cannot identify its parent', async () => { + const f = await fixture() + await f.write('future-root', [], false, 5) + expect((await f.ctx.sessionPersistence.list()).map(row => row.header.id)).toEqual([f.parent]) + await expect(f.read()).rejects.toBeInstanceOf(SessionFormatUnsupportedError) + }) + + it('preserves unsupported child decoding errors instead of reporting parent corruption', async () => { + const f = await fixture() + const path = await f.write('child', [{ type: 'future/required', seq: 0, time: 2, data: {} }], true) + await expect(f.read()).rejects.toBeInstanceOf(SessionFormatUnsupportedError) + await expect(f.read()).rejects.toThrow(path) + }) + + it('locates incomplete historical descriptor fields at their child source', async () => { + const f = await fixture() + const path = await f.write('child', [{ ...f.descriptor, data: { version: 2, provider: 'spawn', mode: 'unknown' } }], true) + await expect(f.read()).rejects.toBeInstanceOf(SessionFormatUnsupportedError) + await expect(f.read()).rejects.toThrow(path) + }) + + it.each(['read', 'write'] as const)('rejects duplicate own catalogs through a current %s open', async (access) => { + const f = await fixture() + const catalog = { type: 'subagent/catalog', seq: 0, time: 2, + data: { version: 0, childId: 'child', childCreatedAt: 2, mode: 'one-shot' } } + await f.write(f.parent, [catalog, { ...catalog, seq: 1 }], false, 4) + await expect(f.ctx.sessionPersistence.open(f.parent, access)).rejects.toThrow('duplicate catalog child') + }) + + it('recollects a changed child within the same read open', async () => { + const f = await fixture() + await f.write('child', [f.descriptor], true) + expect(await f.read()).toHaveLength(1) + await f.write('child', [f.descriptor, { type: 'feedback/record', seq: 1, time: 3, data: { text: 'appended' } }], true) + expect(await f.read()).toHaveLength(1) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + }) + + it('detects children added after preparation instead of publishing incomplete membership', async () => { + const f = await fixture() + expect(await f.read()).toEqual([]) + await f.write('child', [f.descriptor], true) + await expect(f.ctx.sessionPersistence.open(f.parent, 'write')).rejects.toThrow(generationLogPath(f.root, undefined, SessionId('child'), 3, compression)) + expect(await f.read()).toHaveLength(1) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + }) + + it('recollects newly available discovery fields before publishing a prepared parent', async () => { + const f = await fixture() + const childPath = await f.write('child', [], true) + expect(await f.read()).toEqual([]) + await f.write('child', [f.descriptor], true) + await expect(f.ctx.sessionPersistence.open(f.parent, 'write')).rejects.toThrow(childPath) + const parentPath = generationLogPath(f.root, undefined, f.parent, 3, compression) + expect((await readdir(dirname(parentPath))).filter(name => name !== 'session.lock')) + .toEqual([compression === 'none' ? 'session.v3.jsonl' : 'session.v3.jsonl.zstd']) + expect(await f.read()).toMatchObject([{ type: 'subagent/catalog', data: { childId: 'child', label: 'old child' } }]) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + }) + + it('reads current children without recursive migration and preserves current parent fast reads', async () => { + const f = await fixture() + await f.write('child', [f.descriptor], true, 4) + expect(await f.read()).toHaveLength(1) + await f.write(f.parent, [], false, 4) + await f.write('child', [], true, 4) + expect(await f.read()).toEqual([]) + }) + + it('refuses publication when a related child disappears', async () => { + const f = await fixture() + const path = await f.write('child', [f.descriptor], true) + const header = { ...f.header, id: SessionId('child'), origin: 'subagent', parentSession: f.parent, createdAt: 2, delegationDepth: 1 } as SessionHeader + const prepare = () => prepareCatalogFacts(f.parent, [{ path, header }], compression, new AbortController().signal) + const prepared = await prepare() + await rm(path) + await expect(prepared.validate()).rejects.toMatchObject({ code: 'ENOENT' }) + await expect(prepare()).rejects.toMatchObject({ code: 'ENOENT' }) + }) + + it('rejects changed header identities and invalid source selection', async () => { + const f = await fixture() + const path = await f.write('child', [f.descriptor], true) + const header = { ...f.header, id: SessionId('wrong-child'), origin: 'subagent', parentSession: f.parent } as SessionHeader + const signal = new AbortController().signal + await expect(prepareCatalogFacts(f.parent, [{ path, header }], compression, signal)).rejects.toThrow('changed') + await expect(prepareCatalogFacts(f.parent, [{ path: path + '.foreign', header }], compression, signal)).rejects.toThrow('unrecognized historical child generation') + const controller = new AbortController() + controller.abort(new Error('cancelled child collection')) + await expect(prepareCatalogFacts(f.parent, [{ path, header }], compression, controller.signal)).rejects.toThrow('cancelled child collection') + }) + + it.each([0, 1, 2])('composes a V%i parent and child through all preceding edges', async (version) => { + const f = await fixture() + const initial = generationLogPath(f.root, undefined, f.parent, 3, compression) + await rm(initial) + const parentPath = await f.write(f.parent, [], false, version) + const childPath = await f.write('child', [f.descriptor], true, version) + const before = await Promise.all([readFile(parentPath), readFile(childPath)]) + expect(await f.read()).toMatchObject([{ type: 'subagent/catalog', seq: 0, data: { childId: 'child', mode: 'continuable', label: 'old child' } }]) + const writer = await f.ctx.sessionPersistence.open(f.parent, 'write') + await writer.close() + expect(await Promise.all([readFile(parentPath), readFile(childPath)])).toEqual(before) + expect((await readdir(dirname(parentPath))).filter(name => name !== 'session.lock')).toHaveLength(2) + }) + + it('lists historical headers, prepares read-only membership, and publishes an unchanged-prefix successor', async () => { + const root = await mkdtemp(join(tmpdir(), 'dsh-catalog-migration-')) + roots.push(root) + const parent = SessionId('parent') + const child = SessionId('child') + const header = { type: 'session', version: 3, id: parent, createdAt: 1, isSeeded: false, delegationDepth: 0 } + const childHeader = { ...header, id: child, createdAt: 2, origin: 'subagent', parentSession: parent, delegationDepth: 1 } + const descriptor = { type: 'subagent/descriptor', seq: 0, time: 2, data: { version: 3, mode: 'one-shot', provider: 'spawn', label: 'old child' } } + const sourcePaths: string[] = [] + for (const [meta, events] of [[header, []], [childHeader, [descriptor]]] as const) { + const path = generationLogPath(root, undefined, meta.id, 3, compression) + sourcePaths.push(path) + await mkdir(dirname(path), { recursive: true }) + const first = Buffer.from(JSON.stringify(meta) + '\n') + const body = Buffer.from(events.map(event => JSON.stringify(event) + '\n').join('')) + await writeFile(path, compression === 'none' ? Buffer.concat([first, body]) + : Buffer.concat([await compressZstdFrame(first), ...(body.length === 0 ? [] : [await compressZstdFrame(body)])])) + } + const original = await Promise.all(sourcePaths.map(path => readFile(path))) + const ctx = new Context() + contexts.push(ctx) + await ctx.plugin(JsonlSessionPersistence, { root, compression }) + expect((await ctx.sessionPersistence.list()).map(row => row.header.id).sort()).toEqual([child, parent]) + const reader = await ctx.sessionPersistence.open(parent, 'read') + let expected + try { + expect(reader.header.version).toBe(4) + expected = (await reader.read()).events + expect(expected).toEqual([{ type: 'subagent/catalog', seq: 0, time: 1, data: { + version: 0, childId: child, childCreatedAt: 2, mode: 'one-shot', label: 'old child', + } }]) + expect(await readdir(dirname(sourcePaths[0]!))).toEqual([compression === 'none' ? 'session.v3.jsonl' : 'session.v3.jsonl.zstd']) + } finally { await reader.close() } + const writer = await ctx.sessionPersistence.open(parent, 'write') + try { expect((await writer.read()).events).toEqual(expected) } finally { await writer.close() } + expect(await Promise.all(sourcePaths.map(path => readFile(path)))).toEqual(original) + const reopened = await ctx.sessionPersistence.open(parent, 'read') + try { expect((await reopened.read()).events).toEqual(expected) } finally { await reopened.close() } + }) +}) diff --git a/packages/session/session-persistence-jsonl/tests/content-admission.spec.ts b/packages/session/session-persistence-jsonl/tests/content-admission.spec.ts index 2b27defcf4..e8e088220c 100644 --- a/packages/session/session-persistence-jsonl/tests/content-admission.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/content-admission.spec.ts @@ -1,7 +1,7 @@ /** V2 content admission refuses entire generations without publishing a valid prefix. */ import { Context } from '@deepseek-ai/cordis' -import { SessionId } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' import type { SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' import { SessionFormatUnsupportedError } from '@deepseek-ai/dsh-session-persistence' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' @@ -198,7 +198,7 @@ describe.each(['none', 'zstd'] as const)('V2 admitted content publication (%s)', const reader = await ctx.sessionPersistence.open(id, 'read') const restored = await (async () => { try { - expect(reader.header.version).toBe(3) + expect(reader.header.version).toBe(SESSION_FORMAT_VERSION) return await reader.read() } finally { await reader.close() } })() @@ -219,7 +219,7 @@ describe.each(['none', 'zstd'] as const)('V2 admitted content publication (%s)', expect((await writer.read()).events).toEqual(restored.events) await writer.flush() } finally { await writer.close() } - const successor = generationLogPath(root!, undefined, id, 3, compression) + const successor = generationLogPath(root!, undefined, id, SESSION_FORMAT_VERSION, compression) const published = await readFile(successor) let decoded = published if (compression === 'zstd') { @@ -237,7 +237,7 @@ describe.each(['none', 'zstd'] as const)('V2 admitted content publication (%s)', const fresh = await mount(compression) const reopened = await fresh.sessionPersistence.open(id, 'read') try { - expect(reopened.header.version).toBe(3) + expect(reopened.header.version).toBe(SESSION_FORMAT_VERSION) expect((await reopened.read()).events).toEqual(restored.events) } finally { await reopened.close() } expect(await observe(path)).toEqual(original) diff --git a/packages/session/session-persistence-jsonl/tests/current-event-admission.spec.ts b/packages/session/session-persistence-jsonl/tests/current-event-admission.spec.ts new file mode 100644 index 0000000000..b7cbb7e6ee --- /dev/null +++ b/packages/session/session-persistence-jsonl/tests/current-event-admission.spec.ts @@ -0,0 +1,88 @@ +import { Context } from '@deepseek-ai/cordis' +import { SESSION_FORMAT_VERSION, SessionId, SessionSeq } from '@deepseek-ai/dsh-session' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { generationLogPath, scanLog } from '../src/format.ts' + +const id = SessionId('current-admission') +const header = { type: 'session', version: SESSION_FORMAT_VERSION, id, createdAt: 1000, isSeeded: false, delegationDepth: 0 } +const start = { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } } +const prefix = [header, start].map(row => JSON.stringify(row)).join('\n') + '\n' +const obsoleteTypes = ['tool/code-dispatch-start', 'tool/code-dispatch'] as const + +function obsoleteEvent(type: string, ignorable?: true) { + return { + type, seq: 1, time: 2, + data: { rootCallId: 'root', parentCallId: 'root', subCallId: 'child', name: 'read', arguments: {} }, + ...(ignorable ? { ignorable } : {}), + } +} + +describe('current event admission at EOF', () => { + let root: string + let ctx: Context + + beforeEach(async () => { + root = await mkdtemp(join(tmpdir(), 'dsh-current-admission-')) + ctx = new Context() + await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' }) + }) + + afterEach(async () => { + try { + await ctx?.fiber.dispose() + } finally { + if (root !== undefined) await rm(root, { recursive: true, force: true }) + } + }) + + async function store(bytes: Buffer): Promise { + const path = generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, 'none') + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, bytes) + return path + } + + it.each([{ surfaceOp: 'append' }, { sourceEventSeqs: [] }])('refuses unknown required metadata %j without truncating a provider append', async (metadata) => { + const event = { type: 'future/required', seq: 0, time: 1, data: {}, ...metadata } + const bytes = Buffer.from([header, event].map(row => JSON.stringify(row)).join('\n') + '\n') + expect(scanLog(bytes)).toMatchObject({ events: [event], committedBytes: bytes.length }) + const path = await store(bytes) + const sourceStat = await stat(path) + for (const access of ['read', 'write'] as const) { + const operation = async () => { + const handle = await ctx.sessionPersistence.open(id, access) + try { + if (access === 'read') await handle.read() + else await handle.append([{ type: 'turn/start', seq: SessionSeq(1), time: 2, data: { turn: 1 } }]) + } finally { + await handle.close() + } + } + await expect(operation()).rejects.toThrow('unknown to this harness and not marked ignorable') + expect(await readFile(path)).toEqual(bytes) + expect(await stat(path)).toMatchObject({ dev: sourceStat.dev, ino: sourceStat.ino }) + } + }) + + it.each(obsoleteTypes)('retains ignorable %s through scanning and a provider append', async (type) => { + const event = obsoleteEvent(type, true) + const bytes = Buffer.from(prefix + JSON.stringify(event) + '\n') + expect(scanLog(bytes)).toMatchObject({ events: [start, event], committedBytes: bytes.length }) + const path = await store(bytes) + const writer = await ctx.sessionPersistence.open(id, 'write') + try { + expect((await writer.read()).events).toEqual([start, event]) + await writer.append([{ + type: 'turn/end', seq: SessionSeq(2), time: 3, data: { turn: 1, reason: { kind: 'completed' } }, + }]) + } finally { + await writer.close() + } + expect((await readFile(path)).subarray(0, bytes.length)).toEqual(bytes) + }) + +}) diff --git a/packages/session/session-persistence-jsonl/tests/generation.spec.ts b/packages/session/session-persistence-jsonl/tests/generation.spec.ts index 41db8b8ea0..4d398dca4b 100644 --- a/packages/session/session-persistence-jsonl/tests/generation.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/generation.spec.ts @@ -1,3 +1,4 @@ +import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session' import { afterEach, describe, expect, it, vi } from 'vitest' import { createHash } from 'node:crypto' import { @@ -22,6 +23,7 @@ import { JsonlGenerationTargetConflictError, JsonlGenerationUnsupportedMigrationError, prepareJsonlMigration, + readDecodedJsonlSource, verifyJsonlCurrentGeneration, type JsonlGenerationFormatAdapter, type PrepareJsonlMigrationOptions, @@ -29,7 +31,7 @@ import { import { createJsonlGenerationTestRuntime } from '../src/testing/generation.ts' import { compressZstdFrame, decompressZstdFrame, scanZstdFrames } from '../src/zstd.ts' import type { JsonlCompression } from '../src/format.ts' -import { sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' +import { createSessionFormatCatalogWithChildren, sessionFormatCatalog } from '@deepseek-ai/dsh-session-format-catalog' import type { SessionFormatArtifact, SessionFormatEvent, @@ -84,6 +86,20 @@ function header(version: number, id = 'generation-test'): Record { + const path = join(await tempRoot(), 'session.v3.jsonl') + await writeFile(path, line(header(3))) + const controller = new AbortController() + const reason = new Error('child decoding cancelled') + await expect(readDecodedJsonlSource(path, 3, 'none', { + createRestore() { + controller.abort(reason) + throw reason + }, + }, controller.signal)).rejects.toBe(reason) +}) + const assistantUsage = { inputTokens: 3, outputTokens: 2 } const assistantReplayState = { response: { id: 'response' } } @@ -145,7 +161,7 @@ interface TestGenerationFormatAdapter extends JsonlGenerationFormatAdapter { } function adapter(overrides: Partial = {}): TestGenerationFormatAdapter { - const currentVersion = overrides.currentVersion ?? 3 + const currentVersion = overrides.currentVersion ?? SESSION_FORMAT_VERSION return { currentVersion, createRestore(headerValue) { @@ -178,7 +194,7 @@ function adapter(overrides: Partial = {}): TestGene function catalogAdapter(): JsonlGenerationFormatAdapter { return { currentVersion: sessionFormatCatalog.currentVersion, - createRestore: header => sessionFormatCatalog.createRestore(header, { + createRestore: header => createSessionFormatCatalogWithChildren([]).createRestore(header, { recovery: 'recoverable', validation: 'transformed', }), encodeHeader: (header, inheritedEventCount) => @@ -287,7 +303,7 @@ async function decodeZstdJsonl(path: string): Promise { } describe('JSONL immutable generation publication', () => { - it('refuses V2 messages without surface markers before writing a V3 successor', async () => { + it('refuses V2 messages without surface markers before writing a current successor', async () => { const root = await tempRoot() const request = options(root, 'none', catalogAdapter(), 2) const events = assistantLifecycle('assistant/message', assistantData()) @@ -332,7 +348,7 @@ describe('JSONL immutable generation publication', () => { expect(await readdir(root)).toEqual(['session.v2.jsonl']) }) - it('publishes canonical V3 replacements and headers while retaining exact V2 bytes', async () => { + it('publishes canonical replacements and current headers while retaining exact V2 bytes', async () => { const root = await tempRoot() const request = options(root, 'none', catalogAdapter(), 2) const config = { provider: 'mock', model: 'mock' } @@ -345,7 +361,7 @@ describe('JSONL immutable generation publication', () => { { type: 'user/message', seq: 3, time: 5, surfaceOp: { op: 'replace', start: 2, end: 2 }, sourceEventSeqs: [2], data: { id: 'summary', role: 'user', content: [{ type: 'text', text: 'summary' }], - source: { kind: 'plugin', plugin: 'summary-fixture' }, + source: { kind: 'plugin', plugin: 'summary-fixture', form: 'notice', summary: 'summary-fixture' }, } }, { type: 'request/header', seq: 4, time: 6, data: { header: { config, system: '', tools: [], adapterDefaults: {} }, reason: 'initial', @@ -360,7 +376,10 @@ describe('JSONL immutable generation publication', () => { events[0], events[1], expect.objectContaining({ type: 'system/message', seq: 2, surfaceOp: 'append', data: expect.objectContaining({ message: expect.objectContaining({ role: 'system', content: [] }) as unknown }) as unknown }) as unknown, ...events.slice(2).map(event => event.seq === 3 - ? { ...event, seq: 4, surfaceOp: { op: 'replace', startSeq: 3, endSeq: 3 }, sourceEventSeqs: [3] } + ? { ...event, seq: 4, surfaceOp: { op: 'replace', startSeq: 3, endSeq: 3 }, sourceEventSeqs: [3], + data: { ...event.data as Record, source: { + kind: 'plugin:summary-fixture', form: 'notice', summary: 'summary-fixture', + } } } : event.seq === 4 ? { ...event, seq: 5, data: { header: { config }, reason: 'initial' } } : { ...event, seq: event.seq + 1 }), ] @@ -370,8 +389,8 @@ describe('JSONL immutable generation publication', () => { expect(await readFile(request.sourcePath)).toEqual(source) const written = (await readFile(request.currentPath, 'utf8')).trimEnd().split('\n') .map(row => JSON.parse(row) as unknown) - expect(written).toEqual([header(3), ...canonical]) - expect((await readdir(root)).sort()).toEqual(['session.v2.jsonl', 'session.v3.jsonl']) + expect(written).toEqual([header(SESSION_FORMAT_VERSION), ...canonical]) + expect((await readdir(root)).sort()).toEqual(['session.v2.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) }) it('returns migrated events while publication is still waiting for verification', async () => { @@ -382,7 +401,10 @@ describe('JSONL immutable generation publication', () => { ...boundaryBase, data: { ...boundaryBase.data, text: 'x'.repeat(1024 * 1024 - JSON.stringify(boundaryBase).length) }, } - const largeEvent = { ...event0, seq: 1, data: { turn: 1, text: 'y'.repeat(1024 * 1024) } } + const largeEvent = { type: 'user/message', seq: 1, time: 3, surfaceOp: 'append', data: { + id: 'large-message', role: 'user', source: { kind: 'user' }, + content: [{ type: 'text', text: 'y'.repeat(1024 * 1024) }], + } } const finalEvent = { ...event1, seq: 2 } await writeFile(request.sourcePath, line(header(0)) + line(boundaryEvent) + line(largeEvent) + line(finalEvent)) let now = 0 @@ -407,7 +429,7 @@ describe('JSONL immutable generation publication', () => { release.resolve(undefined) await publication const [writtenHeader, ...writtenEvents] = (await readFile(request.currentPath, 'utf8')).trimEnd().split('\n') - expect(JSON.parse(writtenHeader as string)).toEqual({ ...header(3), isSeeded: false }) + expect(JSON.parse(writtenHeader as string)).toEqual({ ...header(SESSION_FORMAT_VERSION), isSeeded: false }) expect(writtenEvents.map(row => JSON.parse(row) as unknown)).toEqual([boundaryEvent, largeEvent, finalEvent]) }) @@ -487,14 +509,14 @@ describe('JSONL immutable generation publication', () => { it('verifies exact current identity, completeness, and event count', async () => { const root = await tempRoot() - const path = generationPath(root, 3, 'none') - await writeFile(path, line({ ...header(3), isSeeded: false }) + line(event0)) + const path = generationPath(root, SESSION_FORMAT_VERSION, 'none') + await writeFile(path, line({ ...header(SESSION_FORMAT_VERSION), isSeeded: false }) + line(event0)) await expect(verifyJsonlCurrentGeneration(path, 'none', 'other', 1)) .rejects.toThrow('expected "other"') await expect(verifyJsonlCurrentGeneration(path, 'none', 'generation-test', 2)) .rejects.toThrow('contains 1 events') - await writeFile(path, line({ ...header(3), isSeeded: false }) + JSON.stringify(event0)) + await writeFile(path, line({ ...header(SESSION_FORMAT_VERSION), isSeeded: false }) + JSON.stringify(event0)) await expect(verifyJsonlCurrentGeneration(path, 'none', 'generation-test', 1)) .rejects.toThrow('torn physical tail') @@ -503,7 +525,7 @@ describe('JSONL immutable generation publication', () => { .rejects.toThrow('empty or header-less') await expect(verifyJsonlCurrentGeneration(path, 'zstd', 'generation-test', 0)) .rejects.toThrow('empty or header-less Zstandard') - const headerFrame = await compressZstdFrame(line({ ...header(3), isSeeded: false })) + const headerFrame = await compressZstdFrame(line({ ...header(SESSION_FORMAT_VERSION), isSeeded: false })) await writeFile(path, Buffer.concat([headerFrame, await compressZstdFrame(JSON.stringify(event0))])) await expect(verifyJsonlCurrentGeneration(path, 'zstd', 'generation-test', 1)) .rejects.toThrow('torn physical tail') @@ -517,9 +539,9 @@ describe('JSONL immutable generation publication', () => { it('keeps complete Assistant stream checks in current-generation verification', async () => { const root = await tempRoot() - const path = generationPath(root, 3, 'none') + const path = generationPath(root, SESSION_FORMAT_VERSION, 'none') const verify = async (events: readonly SessionFormatEvent[]) => { - await writeFile(path, line(header(3)) + events.map(line).join('')) + await writeFile(path, line(header(SESSION_FORMAT_VERSION)) + events.map(line).join('')) return verifyJsonlCurrentGeneration(path, 'none', 'generation-test', events.length) } @@ -573,7 +595,7 @@ describe('JSONL immutable generation publication', () => { const differentRoot = await tempRoot() const different = options(differentRoot, 'none', streamingAdapter()) await writeFile(different.sourcePath, line(header(0)) + line(event0)) - await writeFile(different.currentPath, line({ ...header(3), isSeeded: false }) + line({ ...event0, time: 99 })) + await writeFile(different.currentPath, line({ ...header(SESSION_FORMAT_VERSION), isSeeded: false }) + line({ ...event0, time: 99 })) const conflicted = await prepareJsonlMigration({ ...different, verifyCurrentFile: verifier(), @@ -585,7 +607,7 @@ describe('JSONL immutable generation publication', () => { await writeFile(unchecked.sourcePath, line(header(0)) + line(event0)) await writeFile( unchecked.currentPath, - line({ ...header(3), isSeeded: false }) + line({ ...event0, time: 99 }), + line({ ...header(SESSION_FORMAT_VERSION), isSeeded: false }) + line({ ...event0, time: 99 }), ) const uncheckedPublication = await prepareJsonlMigration({ ...unchecked, @@ -641,8 +663,8 @@ describe('JSONL immutable generation publication', () => { it('checks migration and verification identities exactly', async () => { const verifyRoot = await tempRoot() - const currentPath = generationPath(verifyRoot, 3, 'none') - await writeFile(currentPath, line(header(3))) + const currentPath = generationPath(verifyRoot, SESSION_FORMAT_VERSION, 'none') + await writeFile(currentPath, line(header(SESSION_FORMAT_VERSION))) let statCount = 0 await expect(createJsonlGenerationTestRuntime({ fs: { stat: async path => ({ ...await stat(path, { bigint: true }), ctimeNs: BigInt(++statCount) }) }, @@ -665,7 +687,7 @@ describe('JSONL immutable generation publication', () => { }) await expect(mismatched.publish()).rejects.toThrow('changed during verification') - const current = options(await tempRoot(), 'none', streamingAdapter(), 3) + const current = options(await tempRoot(), 'none', streamingAdapter(), SESSION_FORMAT_VERSION) await expect(prepareJsonlMigration({ ...current, verifyCurrentFile: vi.fn() })) .rejects.toThrow('requires a historical source') @@ -735,10 +757,10 @@ describe('JSONL immutable generation publication', () => { verifyCurrentFile: verifier(), }) await winPrepared.publish() - expect(await readFile(win.currentPath, 'utf8')).toContain('"version":3') + expect(await readFile(win.currentPath, 'utf8')).toContain(`"version":${SESSION_FORMAT_VERSION}`) }) - it('publishes v3 beside an immutable suffixless v0 source', async () => { + it('publishes the current generation beside an immutable suffixless v0 source', async () => { const root = await tempRoot() const request = { ...options(root), signal: new AbortController().signal } const source = Buffer.from(line(header(0)) + line(event0)) @@ -749,13 +771,13 @@ describe('JSONL immutable generation publication', () => { expect(result).toMatchObject({ status: 'migrated', fromVersion: 0, - toVersion: 3, + toVersion: SESSION_FORMAT_VERSION, path: request.currentPath, sourcePath: request.sourcePath, }) expect(await readFile(request.sourcePath)).toEqual(source) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) - expect((await readdir(root)).sort()).toEqual(['session.jsonl', 'session.v3.jsonl']) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) + expect((await readdir(root)).sort()).toEqual(['session.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) }) it.each(['none', 'zstd'] as const)( @@ -884,15 +906,15 @@ describe('JSONL immutable generation publication', () => { createRestore: (value) => { const restore = wrongBase.createRestore(value) return { - header: { ...restore.header, version: 4 }, + header: { ...restore.header, version: SESSION_FORMAT_VERSION + 1 }, decodeRow: (row) => { restore.decodeRow(row) }, finish: () => { const artifact = restore.finish() - return { ...artifact, header: { ...artifact.header, version: 4 } } + return { ...artifact, header: { ...artifact.header, version: SESSION_FORMAT_VERSION + 1 } } }, } }, - })))).rejects.toThrow('format migration returned v4, expected v3') + })))).rejects.toThrow(`format migration returned v${SESSION_FORMAT_VERSION + 1}, expected v${SESSION_FORMAT_VERSION}`) expect(await readdir(blockedRoot)).toEqual(['session.jsonl']) expect(await readdir(ordinaryRoot)).toEqual(['session.jsonl']) expect(await readdir(wrongRoot)).toEqual(['session.jsonl']) @@ -933,8 +955,8 @@ describe('JSONL immutable generation publication', () => { expect(await readFile(request.sourcePath)).toEqual(source) const sourceAfter = await stat(request.sourcePath, { bigint: true }) expect([sourceAfter.dev, sourceAfter.ino]).toEqual([sourceBefore.dev, sourceBefore.ino]) - expect(await readFile(request.currentPath, 'utf8')).toBe(line({ ...header(3), isSeeded: false }) + line(event0)) - expect((await readdir(root)).sort()).toEqual(['session.jsonl', 'session.v3.jsonl']) + expect(await readFile(request.currentPath, 'utf8')).toBe(line({ ...header(SESSION_FORMAT_VERSION), isSeeded: false }) + line(event0)) + expect((await readdir(root)).sort()).toEqual(['session.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) }) it.each(['none', 'zstd'] as const)( @@ -958,7 +980,7 @@ describe('JSONL immutable generation publication', () => { const currentText = compression === 'zstd' ? await decodeZstdJsonl(request.currentPath) : await readFile(request.currentPath, 'utf8') - expect(currentText).toBe(line(header(3)) + line(event0)) + expect(currentText).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }, ) @@ -984,9 +1006,9 @@ describe('JSONL immutable generation publication', () => { await ensureJsonlGenerationCurrent(emptyTailRequest) await ensureJsonlGenerationCurrent(tornRequest) - expect(await decodeZstdJsonl(headerRequest.currentPath)).toBe(line(header(3))) - expect(await decodeZstdJsonl(emptyTailRequest.currentPath)).toBe(line(header(3))) - expect(await decodeZstdJsonl(tornRequest.currentPath)).toBe(line(header(3)) + line(event0) + line(event1)) + expect(await decodeZstdJsonl(headerRequest.currentPath)).toBe(line(header(SESSION_FORMAT_VERSION))) + expect(await decodeZstdJsonl(emptyTailRequest.currentPath)).toBe(line(header(SESSION_FORMAT_VERSION))) + expect(await decodeZstdJsonl(tornRequest.currentPath)).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0) + line(event1)) }) it('rejects header-less raw and Zstandard sources and a non-independent Zstandard header frame', async () => { @@ -1044,7 +1066,7 @@ describe('JSONL immutable generation publication', () => { await expect(ensureJsonlGenerationCurrent(refused)).rejects.toThrow('row 2 is not valid JSON') expect(await readFile(dropped.sourcePath, 'utf8')).toBe(incomplete) - expect(await readFile(dropped.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(dropped.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) expect(await readFile(refused.sourcePath, 'utf8')).toBe(committed) expect(await readdir(refusedRoot)).toEqual(['session.jsonl']) }) @@ -1058,7 +1080,7 @@ describe('JSONL immutable generation publication', () => { await ensureJsonlGenerationCurrent(request) expect(await readFile(request.sourcePath)).toEqual(source) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('validates canonical lowercase generation filenames and one shared directory', async () => { @@ -1072,11 +1094,11 @@ describe('JSONL immutable generation publication', () => { message: 'source path must end with "session.jsonl"', }, { - request: { ...options(root), currentPath: join(root, 'session.V3.jsonl') }, - message: 'current JSONL generation path must end with "session.v3.jsonl"', + request: { ...options(root), currentPath: join(root, `session.V${SESSION_FORMAT_VERSION}.jsonl`) }, + message: `current JSONL generation path must end with "session.v${SESSION_FORMAT_VERSION}.jsonl"`, }, { - request: { ...options(root), currentPath: generationPath(other, 3, 'none') }, + request: { ...options(root), currentPath: generationPath(other, SESSION_FORMAT_VERSION, 'none') }, message: 'must share one Session directory', }, ] @@ -1160,7 +1182,7 @@ describe('JSONL immutable generation publication', () => { expect((await readdir(root)).sort()).toEqual([ 'session.jsonl', 'session.migration.collision.jsonl.tmp', - 'session.v3.jsonl', + `session.v${SESSION_FORMAT_VERSION}.jsonl`, ]) }) @@ -1168,7 +1190,7 @@ describe('JSONL immutable generation publication', () => { const root = await tempRoot() const request = options(root) const source = Buffer.from(line(header(0)) + line(event0)) - const current = Buffer.from(line(header(3)) + line(event0)) + const current = Buffer.from(line(header(SESSION_FORMAT_VERSION)) + line(event0)) await writeFile(request.sourcePath, source) await writeFile(request.currentPath, current) @@ -1177,7 +1199,7 @@ describe('JSONL immutable generation publication', () => { expect(result).toMatchObject({ status: 'migrated', path: request.currentPath }) expect(await readFile(request.sourcePath)).toEqual(source) expect(await readFile(request.currentPath)).toEqual(current) - expect((await readdir(root)).sort()).toEqual(['session.jsonl', 'session.v3.jsonl']) + expect((await readdir(root)).sort()).toEqual(['session.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) }) it.each(['none', 'zstd'] as const)( @@ -1189,8 +1211,8 @@ describe('JSONL immutable generation publication', () => { ? await encodeZstd(0, [event0]) : Buffer.from(line(header(0)) + line(event0)) const expected = compression === 'zstd' - ? await encodeZstd(3, [event0]) - : Buffer.from(line(header(3)) + line(event0)) + ? await encodeZstd(SESSION_FORMAT_VERSION, [event0]) + : Buffer.from(line(header(SESSION_FORMAT_VERSION)) + line(event0)) const appended = compression === 'zstd' ? await compressZstdFrame(line(event1)) : Buffer.from(line(event1)) @@ -1211,11 +1233,11 @@ describe('JSONL immutable generation publication', () => { const request = options(root) const expected = join(root, 'expected.jsonl') await writeFile(request.sourcePath, line(header(0)) + line(event0)) - await writeFile(expected, line(header(3)) + line(event0)) + await writeFile(expected, line(header(SESSION_FORMAT_VERSION)) + line(event0)) await link(expected, request.currentPath) await expect(ensureJsonlGenerationCurrent(request)).resolves.toMatchObject({ path: request.currentPath }) - expect(await readFile(expected, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(expected, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it.each(['different', 'malformed', 'symlink', 'directory'] as const)( @@ -1225,7 +1247,7 @@ describe('JSONL immutable generation publication', () => { const request = options(root) const source = Buffer.from(line(header(0)) + line(event0)) await writeFile(request.sourcePath, source) - if (kind === 'different') await writeFile(request.currentPath, line(header(3)) + line(event1)) + if (kind === 'different') await writeFile(request.currentPath, line(header(SESSION_FORMAT_VERSION)) + line(event1)) if (kind === 'malformed') await writeFile(request.currentPath, '{not-json}\n') if (kind === 'symlink') await symlink(request.sourcePath, request.currentPath) if (kind === 'directory') await mkdir(request.currentPath) @@ -1252,7 +1274,7 @@ describe('JSONL immutable generation publication', () => { }, } await writeFile(request.sourcePath, line(header(0)) + line(event0)) - await writeFile(request.currentPath, line(header(3)) + line(event0)) + await writeFile(request.currentPath, line(header(SESSION_FORMAT_VERSION)) + line(event0)) const failure = await ensureJsonlGenerationCurrent(request).then( () => undefined, @@ -1281,10 +1303,10 @@ describe('JSONL immutable generation publication', () => { request, { platform: 'darwin', fs: { open: openFile } }, )).rejects.toBe(directorySyncFailure) - expect((await readdir(root)).sort()).toEqual(['session.jsonl', 'session.v3.jsonl']) + expect((await readdir(root)).sort()).toEqual(['session.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) await expect(ensureJsonlGenerationCurrent(request)).resolves.toMatchObject({ path: request.currentPath }) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('retains a committed generation when its post-publication stat fails', async () => { @@ -1302,7 +1324,7 @@ describe('JSONL immutable generation publication', () => { }, }, })).rejects.toBe(statFailure) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) expect((await readdir(root)).every(name => !name.includes('.tmp'))).toBe(true) }) @@ -1318,7 +1340,7 @@ describe('JSONL immutable generation publication', () => { if (phase === 'after-publication') controller.abort(reason) }, })).resolves.toMatchObject({ status: 'migrated', path: request.currentPath }) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('rejects a noncanonical case-insensitive collision instead of accepting its bytes', async () => { @@ -1330,12 +1352,12 @@ describe('JSONL immutable generation publication', () => { platform: 'darwin', fs: posixSimulationFs({ link: async () => { throw fsError('EEXIST') }, - readdir: async () => ['session.V3.jsonl'], + readdir: async () => [`session.V${SESSION_FORMAT_VERSION}.jsonl`], }), }).then(() => undefined, (error: unknown) => error) if (!(failure instanceof JsonlGenerationTargetConflictError)) throw new Error('expected target conflict') - expect(failure.reason.message).toContain('noncanonical directory entry "session.V3.jsonl"') + expect(failure.reason.message).toContain(`noncanonical directory entry "session.V${SESSION_FORMAT_VERSION}.jsonl"`) expect((await readdir(root)).every(name => !name.includes('.tmp'))).toBe(true) }) @@ -1365,7 +1387,7 @@ describe('JSONL immutable generation publication', () => { }, })).resolves.toMatchObject({ status: 'migrated', path: request.currentPath }) expect(reads).not.toContain(request.currentPath) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('leaves a crash-style staging file inert', async () => { @@ -1378,7 +1400,7 @@ describe('JSONL immutable generation publication', () => { await ensureJsonlGenerationCurrent(request) expect(await readFile(crashStage, 'utf8')).toBe(line(header(99))) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('removes an exclusively created stage when writing or syncing it fails', async () => { @@ -1499,7 +1521,7 @@ describe('JSONL immutable generation publication', () => { }), })).resolves.toMatchObject({ status: 'migrated', path: request.currentPath }) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('surfaces candidate validation errors and cleanup errors without publishing', async () => { @@ -1534,7 +1556,7 @@ describe('JSONL immutable generation publication', () => { if (!path.includes('.tmp')) return bytes if (mode === 'torn') return bytes.subarray(0, -1) if (mode === 'old') return Buffer.from(line(header(0)) + line(event0)) - return Buffer.from(line(header(3)) + '{not-json}\n') + return Buffer.from(line(header(SESSION_FORMAT_VERSION)) + '{not-json}\n') } await expect(ensureWithOverrides( @@ -1544,7 +1566,7 @@ describe('JSONL immutable generation publication', () => { mode === 'torn' ? 'current session generation has a torn physical tail' : mode === 'old' - ? 'uses log format v0, older than the supported v3' + ? `uses log format v0, older than the supported v${SESSION_FORMAT_VERSION}` : 'unparsable committed event at line 1', ) expect(await readdir(root)).toEqual(['session.jsonl']) @@ -1563,7 +1585,7 @@ describe('JSONL immutable generation publication', () => { expect(publishNewWin32).toHaveBeenCalledOnce() expect(publishNewWin32.mock.calls[0]?.[1]).toBe(request.currentPath) expect(await readFile(request.sourcePath)).toEqual(source) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('accepts an identical target that wins Windows publication', async () => { @@ -1571,7 +1593,7 @@ describe('JSONL immutable generation publication', () => { const request = options(root) await writeFile(request.sourcePath, line(header(0)) + line(event0)) const publishNewWin32 = vi.fn(async (_from: string, to: string) => { - await writeFile(to, line(header(3)) + line(event0)) + await writeFile(to, line(header(SESSION_FORMAT_VERSION)) + line(event0)) throw fsError('EEXIST') }) @@ -1614,7 +1636,7 @@ describe('JSONL immutable generation publication', () => { ) expect(raced).toBe(true) - expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(3)) + line(event0)) + expect(await readFile(request.currentPath, 'utf8')).toBe(line(header(SESSION_FORMAT_VERSION)) + line(event0)) }) it('honors cancellation before reading a generation', async () => { diff --git a/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts b/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts index 854aa5226b..d57a4d91a1 100644 --- a/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts @@ -199,7 +199,7 @@ function withMigratedEmptyHead(log: readonly SessionEvent[]): readonly unknown[] type: 'system/message', seq: 2, time: log[1]!.time, surfaceOp: 'append', data: { turn: 1, step: 1, message: { id: expect.stringMatching(/^v2-to-v3-system-[0-9a-f]{64}$/) as unknown, - role: 'system', content: [], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, + role: 'system', content: [], source: { kind: 'system-prompt' }, } }, }, ...log.slice(2).map(event => ({ ...event, seq: SessionSeq(event.seq + 1) })), @@ -439,7 +439,7 @@ describe('JsonlSessionPersistence: format helpers', () => { ['unseeded', false, 0], ['empty-seed', true, 0], ['nonempty-seed', true, 3], - ] as const)('round-trips v3 lineage markers for %s', (_case, isSeeded, inheritedEventCount) => { + ] as const)('round-trips current lineage markers for %s', (_case, isSeeded, inheritedEventCount) => { const events = isSeeded ? [ ...Array.from({ length: inheritedEventCount }, (_, seq) => ({ @@ -470,7 +470,7 @@ describe('JsonlSessionPersistence: format helpers', () => { expect(toHeaderLine(scanned.meta, scanned.inheritedEventCount)).toStrictEqual(line) }) - it('rejects a v3 physical header without explicit isSeeded', () => { + it('rejects a current physical header without explicit isSeeded', () => { const { isSeeded: _isSeeded, ...line } = toHeaderLine(meta('missing-is-seeded')) expect(() => scanLog(Buffer.from(`${JSON.stringify(line)}\n`))).toThrow(/session header/) }) @@ -666,16 +666,17 @@ describe('JsonlSessionPersistence: stored-format refusals', () => { .rejects.toThrow(/contains event type "request\/header-delta" \(seq 1\) unknown to this harness/) }) - it('rejects a stored v0 full header carrying the legacy fallback reason', async () => { + it('rejects a stored full header carrying the legacy fallback reason', async () => { const m = meta('legacy-header-fallback', '/legacy') const path = rawLogPath(root, m.cwd, m.id) await mkdir(sessionDir(root, m.cwd, m.id), { recursive: true }) await writeFile(path, [ JSON.stringify(toHeaderLine(m)), + JSON.stringify({ type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1 } }), JSON.stringify({ type: 'request/header', - seq: SessionSeq(0), - time: 1, + seq: SessionSeq(1), + time: 2, data: { header: { config: { provider: 'mock', model: 'legacy' } }, reason: 'fallback' }, }), '', @@ -697,8 +698,52 @@ describe('JsonlSessionPersistence: immutable format generations', () => { afterEach(async () => { await ctx.fiber.dispose() }) + it.each([3, SESSION_FORMAT_VERSION])('shares deeply frozen opaque JSON from format v%s', async (version) => { + type NestedValue = { + values: [null, boolean, number, string, unknown[]] + __proto__: { leaf: number } + constructor: { leaf: number } + } + const data = JSON.parse('{"nested":[[{"values":[null,true,7,"text",[]],"__proto__":{"leaf":1},"constructor":{"leaf":2}}]]}') as { nested: [[NestedValue]] } + const header = meta(`frozen-json-v${version}`, '/work') + const path = generationLogPath(root, header.cwd, header.id, version, 'none') + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, [ + { ...toHeaderLine(header), version }, + { type: 'external/frozen-json', seq: 0, time: 1, ignorable: true, data }, + ].map(row => JSON.stringify(row) + '\n').join('')) + + const handle = await ctx.sessionPersistence.open(header.id, 'read') + try { + const read = await handle.read() + expect(read.eventState).toBe('shared-frozen') + expect(read.events).toHaveLength(1) + const event = read.events[0] as SessionEvent + const actual = event.data as unknown as typeof data + const nested = actual.nested[0][0] + expect(actual).toEqual(data) + expect(Object.getPrototypeOf(nested)).toBe(Object.prototype) + expect(Object.hasOwn(nested, '__proto__')).toBe(true) + expect(Object.hasOwn(nested, 'constructor')).toBe(true) + expect([ + event, actual, actual.nested, actual.nested[0], nested, nested.values, + nested.values[4], nested.__proto__, nested.constructor, + ].every(Object.isFrozen)).toBe(true) + expect(Reflect.set(nested.__proto__, 'leaf', 9)).toBe(false) + expect(Reflect.set(nested.constructor, 'leaf', 9)).toBe(false) + expect(() => nested.values[4].push('changed')).toThrow(TypeError) + + const reread = await handle.read() + expect(reread.events).not.toBe(read.events) + expect(reread.events[0]).toBe(event) + expect(reread.events[0]?.data).toBe(actual) + expect(actual).toEqual(data) + } finally { + await handle.close() + } + }) + it('projects a released v0 header through stat and list without reading or mutating its body', async () => { - expect(SESSION_FORMAT_VERSION).toBe(3) const header = meta('released-v0-metadata', '/work') const sourcePath = historicalLogPath(root, header.cwd, header.id) const currentPath = rawLogPath(root, header.cwd, header.id) @@ -972,12 +1017,12 @@ describe('JsonlSessionPersistence: immutable format generations', () => { .toEqual(['session.v1.jsonl']) }) - it('selects v1 from a v0/v1 directory, then v3 from the retained three-generation set', async () => { + it('selects v1 from a v0/v1 directory, then the current generation from the retained three-generation set', async () => { const header = meta('mixed-generation-read', '/work') const directory = sessionDir(root, header.cwd, header.id) const v0Path = historicalLogPath(root, header.cwd, header.id) const v1Path = generationLogPath(root, header.cwd, header.id, 1, 'none') - const v3Path = rawLogPath(root, header.cwd, header.id) + const currentPath = rawLogPath(root, header.cwd, header.id) await mkdir(directory, { recursive: true }) await writeFile(v0Path, `${JSON.stringify(releasedV0Header(header))}\n`) await writeFile(v1Path, releasedV1PackedPhysicalLog(header)) @@ -988,13 +1033,13 @@ describe('JsonlSessionPersistence: immutable format generations', () => { await writer.close() expect((await readdir(directory)).filter(name => name.startsWith('session')).sort()) .toEqual(process.platform === 'win32' - ? ['session.jsonl', 'session.v1.jsonl', 'session.v3.jsonl'] - : ['session.jsonl', 'session.lock', 'session.v1.jsonl', 'session.v3.jsonl']) + ? ['session.jsonl', 'session.v1.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`] + : ['session.jsonl', 'session.lock', 'session.v1.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) await writeFile(v0Path, 'corrupt lower v0\n') await writeFile(v1Path, 'corrupt lower v1\n') await expect(readAll(ctx.sessionPersistence, header.id)).resolves.toEqual(migrated) - expect(await readFile(v3Path, 'utf8')).toContain('"version":3') + expect(await readFile(currentPath, 'utf8')).toContain(`"version":${SESSION_FORMAT_VERSION}`) }) it('does not publish a historical generation through handle storage resolution', async () => { @@ -1073,7 +1118,7 @@ describe('JsonlSessionPersistence: immutable format generations', () => { const writer = await ctx.sessionPersistence.open(header.id, 'write') await writer.close() expect(await readFile(sourcePath, 'utf8')).toBe(`${source}\n`) - expect(await readFile(currentPath, 'utf8')).toContain('"version":3') + expect(await readFile(currentPath, 'utf8')).toContain(`"version":${SESSION_FORMAT_VERSION}`) }) it('finishes publication before rejecting a write open cancelled during publication', async () => { @@ -1089,7 +1134,7 @@ describe('JsonlSessionPersistence: immutable format generations', () => { await expect(ctx.sessionPersistence.open(header.id, 'write', { signal: controller.signal })) .rejects.toBe(reason) - expect(await readFile(currentPath, 'utf8')).toContain('"version":3') + expect(await readFile(currentPath, 'utf8')).toContain(`"version":${SESSION_FORMAT_VERSION}`) const writer = await ctx.sessionPersistence.open(header.id, 'write') await writer.close() }) @@ -1166,6 +1211,25 @@ describe('JsonlSessionPersistence: immutable format generations', () => { .rejects.toThrow(/released v0 physical header lacks required member "type"/) }) + it('tracks a disappearing corpus member and propagates its storage faults in historical revisions', async () => { + const parent = meta('corpus-revision-parent', '/work') + const child = meta('corpus-revision-child', '/work') + for (const header of [parent, child]) { + const path = historicalLogPath(root, header.cwd, header.id) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, `${JSON.stringify(releasedV0Header(header))}\n`) + } + const present = await ctx.sessionPersistence.stat(parent.id) + statFailure.path = historicalLogPath(root, child.cwd, child.id) + statFailure.error = Object.assign(new Error('member disappeared'), { code: 'ENOENT' }) + const missing = await ctx.sessionPersistence.stat(parent.id) + expect(missing).toBeDefined() + expect(missing?.revision).not.toBe(present?.revision) + expect((await ctx.sessionPersistence.stat(parent.id))?.revision).toBe(missing?.revision) + statFailure.error = Object.assign(new Error('member denied'), { code: 'EACCES' }) + await expect(ctx.sessionPersistence.stat(parent.id)).rejects.toBe(statFailure.error) + }) + it('surfaces source-read storage faults and aborts unwrapped during migration', async () => { const header = meta('source-read-fault', '/work') const sourcePath = historicalLogPath(root, header.cwd, header.id) @@ -2012,7 +2076,7 @@ describe('JsonlSessionPersistence: scanLog unit', () => { expect(restored).toMatchObject({ type: 'user/message', surfaceOp: 'append', sourceEventSeqs: [0, 1] }) }) - it('requires the tagged inherited cut to agree with the v3 header lineage', () => { + it('requires the tagged inherited cut to agree with the current header lineage', () => { const seeded = { ...meta('scanner-seeded-cut'), isSeeded: true } const seededHeader = JSON.stringify(toHeaderLine(seeded, SessionLogOffset(0))) expect(() => scanLog(Buffer.from(`${seededHeader}\n`))) @@ -2184,6 +2248,32 @@ describe('JsonlSessionPersistence: scanLog unit', () => { expect(() => scanLog(Buffer.from(log))).toThrow(/seq gap/) }) + it.each([ + ['assistant/message', {}, /assistant\/message requires a message/], + ['agent/inbox/spliced', { inserted: null }, /agent\/inbox\/spliced requires message array/], + ['session/title-llm-request', { messages: [null] }, /session\/title-llm-request requires message objects/], + ])('rejects malformed %s message slots before exposing a native scan', (type, data, error) => { + const prefix = [ + { type: 'session', version: SESSION_FORMAT_VERSION, id: 'malformed-tail', createdAt: 1, isSeeded: false, delegationDepth: 0 }, + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + ].map(row => JSON.stringify(row)).join('\n') + '\n' + const malformed = JSON.stringify({ type, seq: 1, time: 2, data }) + '\n' + expect(() => scanLog(Buffer.from(prefix + malformed))).toThrow(error) + const committed = JSON.stringify({ type: 'turn/end', seq: 2, time: 3, data: { turn: 1, reason: { kind: 'completed' } } }) + '\n' + expect(() => scanLog(Buffer.from(prefix + malformed + committed))).toThrow(error) + }) + + it.each([false, true])('rejects malformed native tool results before recovery (sealed=%s)', (sealed) => { + const rows = [ + { type: 'session', version: SESSION_FORMAT_VERSION, id: 'malformed-tool', createdAt: 1, isSeeded: false, delegationDepth: 0 }, + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { type: 'tool/result', seq: 1, time: 2, data: { message: [] } }, + ...(sealed ? [{ type: 'turn/end', seq: 2, time: 3, data: { turn: 1, reason: { kind: 'completed' } } }] : []), + ] + const log = rows.map(row => JSON.stringify(row)).join('\n') + '\n' + expect(() => scanLog(Buffer.from(log))).toThrow(/tool\/result.*message must be an object/) + }) + it('rejects malformed records before a later committed turn/end', () => { const corruptRecords = [ ['{not json', /unparsable committed event/], @@ -2234,7 +2324,7 @@ describe('JsonlSessionPersistence: scanLog unit', () => { }) }) -describe('JsonlSessionPersistence: nested v3 Assistant streams', () => { +describe('JsonlSessionPersistence: nested Assistant streams', () => { let ctx: Context beforeEach(async () => { root = await freshRoot() @@ -2287,7 +2377,7 @@ describe('JsonlSessionPersistence: nested v3 Assistant streams', () => { expect(loaded.events).toEqual(log) }) - it.each([2, 3])('reads v%s rows and appends a v3 turn without changing predecessor bytes', async (version) => { + it.each([2, 3])('reads v%s rows and appends a current turn without changing predecessor bytes', async (version) => { const m = meta('mixed', '/work') const log = chunkRunLog() const sourcePath = generationLogPath(root, '/work', m.id, version, 'none') @@ -2304,10 +2394,10 @@ describe('JsonlSessionPersistence: nested v3 Assistant streams', () => { const expected = version === 2 ? withMigratedEmptyHead(log) : log const restored = await readAll(ctx.sessionPersistence, m.id) - expect(restored.meta.version).toBe(3) + expect(restored.meta.version).toBe(SESSION_FORMAT_VERSION) expect(restored.events).toEqual(expected) expect(await readFile(sourcePath)).toEqual(source) - if (version === 2) await expect(readFile(currentPath)).rejects.toMatchObject({ code: 'ENOENT' }) + await expect(readFile(currentPath)).rejects.toMatchObject({ code: 'ENOENT' }) const secondTurn: SessionEvent[] = JSON.parse(JSON.stringify(log)) as SessionEvent[] for (const [k, e] of secondTurn.entries()) { ;(e as { seq: number }).seq = expected.length + k @@ -2317,11 +2407,11 @@ describe('JsonlSessionPersistence: nested v3 Assistant streams', () => { const loaded = await readAll(ctx.sessionPersistence, m.id) expect(loaded.events).toEqual([...expected, ...secondTurn]) - expect(currentPath).toBe(join(dirname(sourcePath), 'session.v3.jsonl')) + expect(currentPath).toBe(join(dirname(sourcePath), `session.v${SESSION_FORMAT_VERSION}.jsonl`)) const successor = (await readFile(currentPath, 'utf8')).trimEnd().split('\n') - expect(JSON.parse(successor[0] as string)).toMatchObject({ version: 3 }) + expect(JSON.parse(successor[0] as string)).toMatchObject({ version: SESSION_FORMAT_VERSION }) expect(successor.slice(1).map(row => JSON.parse(row) as unknown)).toEqual([...expected, ...secondTurn]) - if (version === 2) expect(await readFile(sourcePath)).toEqual(source) + expect(await readFile(sourcePath)).toEqual(source) // Compact tags stay nested; physical rows contain only current event tags. const tags = (await readFile(rawLogPath(root, '/work', m.id), 'utf8')).split('\n').filter(Boolean) .map(line => (JSON.parse(line) as { type: string }).type) diff --git a/packages/session/session-persistence-jsonl/tests/migration-refusal.spec.ts b/packages/session/session-persistence-jsonl/tests/migration-refusal.spec.ts index b8d4bb5542..36ecf12c72 100644 --- a/packages/session/session-persistence-jsonl/tests/migration-refusal.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/migration-refusal.spec.ts @@ -1,9 +1,11 @@ -/** Durable EOF refusals preserve historical generations and never fall back from native V3. */ +/** Durable EOF refusals preserve historical generations and never fall back from the selected generation. */ import { Context } from '@deepseek-ai/cordis' -import { SessionId } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' +import { createSessionFormatCatalogWithChildren } from '@deepseek-ai/dsh-session-format-catalog' +import type { SessionEvent } from '@deepseek-ai/dsh-session' import type { SessionFormatJsonObject } from '@deepseek-ai/dsh-session-format' -import { SessionFormatUnsupportedError } from '@deepseek-ai/dsh-session-persistence' +import { SessionFormatUnsupportedError, SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' import { createHash } from 'node:crypto' import { mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises' @@ -29,7 +31,8 @@ const prefix: readonly SessionFormatJsonObject[] = [ { type: 'user/message', data: question, surfaceOp: 'append' }, { type: 'request/header', data: { header: { config, system: 'Inspect the durable audit.' }, reason: 'initial' } }, ] -const nativePrefix: readonly SessionFormatJsonObject[] = [ +/** Released V3 files still carry plugin attribution; current V4 files are producer-owned. */ +const releasedPrefix: readonly SessionFormatJsonObject[] = [ ...prefix.slice(0, 2), { type: 'system/message', surfaceOp: 'append', data: { turn: 1, step: 1, message: { @@ -40,6 +43,69 @@ const nativePrefix: readonly SessionFormatJsonObject[] = [ { type: 'user/message', data: question, surfaceOp: 'append' }, { type: 'request/header', data: { header: { config }, reason: 'initial' } }, ] +const nativePrefix: readonly SessionFormatJsonObject[] = [ + ...prefix.slice(0, 2), + { type: 'system/message', surfaceOp: 'append', data: { + turn: 1, step: 1, message: { + id: 'native-system', role: 'system', source: { kind: 'system-prompt' }, + content: [{ type: 'text', text: 'Inspect the durable audit.' }], + }, + } }, + { type: 'user/message', data: question, surfaceOp: 'append' }, + { type: 'request/header', data: { header: { config }, reason: 'initial' } }, +] + + +function checkpointSource(): SessionFormatJsonObject { + const restore = createSessionFormatCatalogWithChildren([]).createRestore({ + type: 'session', version: 3, id: 'checkpoint-source', createdAt: 0, isSeeded: false, delegationDepth: 0, + }, { recovery: 'strict', validation: 'current' }) + restore.decodeRow({ type: 'user/message', seq: 0, time: 0, surfaceOp: 'append', data: { + ...question, source: { kind: 'plugin', plugin: 'compact' }, + } }) + return (restore.finish().events[0]?.data as SessionFormatJsonObject)['source'] as SessionFormatJsonObject +} + +function nativeCheckpoint(compactionId: string): readonly SessionFormatJsonObject[] { + return [ + ...nativePrefix, + { type: 'compaction/start', data: { compactionId: 'owner', turn: 1 } }, + { type: 'compaction/summary', data: { + compactionId: 'owner', summary: [{ type: 'text', text: 'Summary' }], shadowedRange: { start: 3, end: 3 }, + shadowedSeqs: [3], shadowedTokenCount: 1, provider: config.provider, model: config.model, + } }, + { type: 'user/message', surfaceOp: { op: 'replace', startSeq: 3, endSeq: 3 }, sourceEventSeqs: [3, 5, 6], data: { + ...question, id: 'checkpoint', source: { ...checkpointSource(), compactionId }, + } }, + { type: 'compaction/end', data: { compactionId: 'owner', turn: 1 } }, + { type: 'step/end', data: { turn: 1, step: 1 } }, + { type: 'turn/end', data: { turn: 1, reason: { kind: 'completed' } } }, + ] +} + +function releasedToolRows( + messageFields: SessionFormatJsonObject = {}, wrapperFields: SessionFormatJsonObject = {}, +): SessionFormatJsonObject[] { + return [ + ...releasedPrefix, + { type: 'assistant/message', surfaceOp: 'append', data: { + turn: 1, step: 1, stream: [], message: { + id: 'assistant', role: 'assistant', source: { kind: 'model', provider: config.provider, model: config.model }, + content: [{ type: 'tool-call', id: 'outer-call', name: 'example', arguments: '{}' }], + }, + } }, + { type: 'tool/call', data: { turn: 1, step: 1, callId: 'outer-call', name: 'example', arguments: '{}' } }, + { type: 'tool/result', surfaceOp: 'append', data: { + turn: 1, step: 1, message: { + ...messageFields, id: 'result', role: 'user', source: { kind: 'tool', callId: 'outer-call' }, + content: [{ type: 'tool-result', toolCallId: 'outer-call', isError: false, + content: [{ type: 'text', text: 'result' }], ...wrapperFields }], + }, + } }, + { type: 'step/end', data: { turn: 1, step: 1 } }, + { type: 'turn/end', data: { turn: 1, reason: { kind: 'completed' } } }, + ] +} function ptcRow(type: string): SessionFormatJsonObject { return { type, data: type.endsWith('-start') ? dispatch : { @@ -76,6 +142,8 @@ const nativeRefusals = [ name: type, tail: ptcRow(type), diagnostic: 'format v3 contains unknown event type ' + JSON.stringify(type) + ' at seq ' + String(nativePrefix.length), + currentError: 'unsupported' as const, + currentSubject: type, })), { name: 'retired request/header.system', @@ -83,8 +151,16 @@ const nativeRefusals = [ header: { config, system: 'This prompt must not be discarded.' }, reason: 'change', } }, diagnostic: 'format v3 request/header rejects retired header.system', + currentError: 'corruption' as const, + currentSubject: 'header.system', }, -] satisfies readonly { name: string; tail: SessionFormatJsonObject; diagnostic: string }[] +] satisfies readonly { + name: string + tail: SessionFormatJsonObject + diagnostic: string + currentError: 'unsupported' | 'corruption' + currentSubject: string +}[] const modes = (['none', 'zstd'] as const).flatMap(compression => (['read', 'write'] as const).map(access => ({ compression, access })), @@ -116,7 +192,11 @@ function line(value: unknown): string { return JSON.stringify(value) + '\n' } -async function store(version: 2 | 3, compression: JsonlCompression, rows: readonly SessionFormatJsonObject[]) { +async function store( + version: 2 | 3 | typeof SESSION_FORMAT_VERSION, + compression: JsonlCompression, + rows: readonly SessionFormatJsonObject[], +) { const path = generationLogPath(root, undefined, id, version, compression) const header = { type: 'session', version, id, createdAt: 1000, isSeeded: false, delegationDepth: 0 } const events = rows.map((row, seq) => ({ ...row, seq, time: 1001 + seq })) @@ -144,6 +224,23 @@ async function expectRefusal(ctx: Context, access: 'read' | 'write', path: strin await expect(opened).rejects.toMatchObject({ message, location: { kind: 'jsonl', path } }) } +async function expectCurrentRefusal( + ctx: Context, + access: 'read' | 'write', + path: string, + kind: 'unsupported' | 'corruption', + subject: string, +) { + // Close an unexpectedly successful open before the rejection assertion fails. + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + const expected = kind === 'unsupported' ? SessionFormatUnsupportedError : SessionPersistenceCorruptionError + await expect(opened).rejects.toBeInstanceOf(expected) + await expect(opened).rejects.toThrow(subject) + if (kind === 'unsupported') { + await expect(opened).rejects.toMatchObject({ location: { kind: 'jsonl', path } }) + } +} + async function expectOnlyGenerations(paths: readonly string[]) { const directory = dirname(paths[0]!) // A released write lease keeps session.lock; every other extra entry is forbidden. @@ -152,6 +249,28 @@ async function expectOnlyGenerations(paths: readonly string[]) { } describe.each(modes)('EOF migration refusal ($compression, $access)', ({ compression, access }) => { + async function expectV3Conversion( + rows: readonly SessionFormatJsonObject[], inspect: (events: readonly SessionEvent[]) => void, + ) { + const path = await store(3, compression, rows) + const original = await observe(path) + for (const mode of [access, 'read'] as const) { + const ctx = await mount(compression) + const handle = await ctx.sessionPersistence.open(id, mode) + try { + expect(handle.header.version).toBe(SESSION_FORMAT_VERSION) + const restored = await handle.read() + expect(restored.events.map(event => ({ seq: event.seq, time: event.time }))) + .toEqual(rows.map((_, seq) => ({ seq, time: 1001 + seq }))) + inspect(restored.events) + } finally { + await handle.close() + } + } + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations(access === 'read' ? [path] : [path, generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression)]) + } + it.each(migrationRefusals)('refuses V2 $name without publishing or discarding a tail', async ({ tail, diagnostic }) => { const path = await store(2, compression, [...prefix, tail]) const original = await observe(path) @@ -162,38 +281,247 @@ describe.each(modes)('EOF migration refusal ($compression, $access)', ({ compres expect(await observe(path)).toEqual(original) await expectOnlyGenerations([path]) for (const targetCompression of ['none', 'zstd'] as const) { - await expect(stat(generationLogPath(root, undefined, id, 3, targetCompression))) - .rejects.toMatchObject({ code: 'ENOENT' }) + for (const targetVersion of [3, SESSION_FORMAT_VERSION]) { + await expect(stat(generationLogPath(root, undefined, id, targetVersion, targetCompression))) + .rejects.toMatchObject({ code: 'ENOENT' }) + } } } }) - it.each(nativeRefusals)('refuses native V3 $name instead of falling back to readable V2', async ({ tail, diagnostic }) => { - const lowerPath = await store(2, compression, prefix) - const lower = await observe(lowerPath) - const ctx = await mount(compression) - const reader = await ctx.sessionPersistence.open(id, 'read') - try { - expect(reader.header.version).toBe(3) - const restored = await reader.read() - expect(restored.events.map(event => event.type)).toEqual([ - 'turn/start', 'step/start', 'system/message', 'user/message', 'system/message', 'request/header', - ]) - expect(restored.events.find(event => event.type === 'user/message')?.data).toEqual(question) - } finally { - await reader.close() - } - expect(await observe(lowerPath)).toEqual(lower) - await expectOnlyGenerations([lowerPath]) - - const path = await store(3, compression, [...nativePrefix, tail]) + it('refuses a V3 watermark claiming V4 without publishing a successor', async () => { + const marker = { type: 'session-log-deepseek/delivery-accepted', data: { + sessionId: id, throughSeq: 0, sessionFormatVersion: 4, + } } + const path = await store(3, compression, [...releasedPrefix, marker]) const original = await observe(path) - const message = diagnostic + ' (raw log: ' + path + ')' - for (let attempt = 0; attempt < 2; attempt += 1) { - await expectRefusal(ctx, access, path, message) - expect(await observe(path)).toEqual(original) - expect(await observe(lowerPath)).toEqual(lower) - await expectOnlyGenerations([lowerPath, path]) - } + const ctx = await mount(compression) + await expectRefusal(ctx, access, path, + 'format v3 delivery marker claims target format v4; source v3 artifact remains unchanged (raw log: ' + path + ')') + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) }) + + it.each(['developer/message', 'external/required'])('refuses invalid required V3 %s before publishing', async (type) => { + const row = { type, surfaceOp: 'append', data: { + turn: 1, step: 1, message: { + id: 'invalid-v3', role: 'developer', source: { kind: 'tool-registry' }, content: [], + }, + } } + const path = await store(3, compression, [...releasedPrefix, row]) + const original = await observe(path) + const ctx = await mount(compression) + await expectRefusal(ctx, access, path, + `format v3 contains unknown event type ${JSON.stringify(type)} at seq ${releasedPrefix.length}` + + '; source v3 artifact remains unchanged (raw log: ' + path + ')') + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it.each([5, 99])('retains a V3 watermark claiming V%s unchanged through native reopening', async (sessionFormatVersion) => { + const marker = { type: 'session-log-deepseek/delivery-accepted', data: { + sessionId: id, throughSeq: 0, sessionFormatVersion, + } } + await expectV3Conversion([...releasedPrefix, marker], (events) => { + expect(events).toEqual([...nativePrefix, marker].map((row, seq) => ({ ...row, seq, time: 1001 + seq }))) + }) + }) + + it.each([false, true])('refuses own V3 tool-definition deferLoading=%s without publishing a successor', async (deferLoading) => { + const tool = { name: 'example', description: 'Saved tool definition.', parameters: { type: 'object' }, deferLoading } + const request = { type: 'request/header', data: { header: { config, tools: [tool] }, reason: 'change' } } + const path = await store(3, compression, [...releasedPrefix, request]) + const original = await observe(path) + const ctx = await mount(compression) + await expectRefusal(ctx, access, path, + `format v3 request/header at seq ${releasedPrefix.length}.header.tools[0] contains deferLoading, which is only defined in V4` + + '; source v3 artifact remains unchanged (raw log: ' + path + ')') + await ctx.sessionPersistence.flush() + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it('preserves ordinary V3 tool-definition extension fields unchanged', async () => { + const parameters = { + type: 'object', properties: { deferLoading: { type: 'boolean' } }, deferLoading: true, + default: { type: 'tool-result', toolCallId: 'opaque-call', content: [{ type: 'text', text: 'schema data' }] }, + } + const fields = JSON.parse('{"metadata":{"saved":"original metadata"},"__proto__":{"saved":"prototype"},"constructor":{"saved":"constructor"},"plugin:deferLoading":true}') as SessionFormatJsonObject + const tool = { name: 'example', description: 'Saved tool definition.', parameters, ...fields } + const request = { type: 'request/header', data: { header: { config, tools: [tool] }, reason: 'initial' } } + await expectV3Conversion([...releasedPrefix.slice(0, -1), request], (events) => { + const expected = [...nativePrefix.slice(0, -1), request] + expect(events).toEqual(expected.map((row, seq) => ({ ...row, seq, time: 1001 + seq }))) + const migrated = events.find(event => event.type === 'request/header')?.data.header.tools?.[0] + expect(Object.hasOwn(migrated!, '__proto__')).toBe(true) + expect(Object.getPrototypeOf(migrated!)).toBe(Object.prototype) + expect(Object.hasOwn(migrated!, 'deferLoading')).toBe(false) + }) + }) + + it('leaves a V3 tool definition with only declared fields unchanged', async () => { + const tool = { name: 'example', description: 'Saved tool definition.', parameters: { type: 'object' } } + const request = { type: 'request/header', data: { header: { config, tools: [tool] }, reason: 'initial' } } + await expectV3Conversion([...releasedPrefix.slice(0, -1), request], (events) => { + expect(events).toEqual([...nativePrefix.slice(0, -1), request] + .map((row, seq) => ({ ...row, seq, time: 1001 + seq }))) + const migrated = events.find(event => event.type === 'request/header')?.data.header.tools?.[0] + expect(Object.hasOwn(migrated!, 'metadata')).toBe(false) + }) + }) + + it.each(['tool/code-dispatch-start', 'tool/code-dispatch'])('keeps %s unsupported beyond a damaged native suffix', async (type) => { + const path = await store(SESSION_FORMAT_VERSION, compression, [...nativePrefix, {}, ptcRow(type)]) + const original = await observe(path) + const ctx = await mount(compression) + await expectCurrentRefusal(ctx, access, path, 'unsupported', type) + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it('refuses a native checkpoint owned by a different compaction before exposing a handle', async () => { + const path = await store(SESSION_FORMAT_VERSION, compression, nativeCheckpoint('wrong-owner')) + const original = await observe(path) + const ctx = await mount(compression) + await expectCurrentRefusal(ctx, access, path, 'corruption', 'matching compaction/start') + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it('refuses a native tool result without its advertised call before exposing a handle', async () => { + const path = await store(SESSION_FORMAT_VERSION, compression, [...nativePrefix, { + type: 'tool/result', surfaceOp: 'append', data: { turn: 1, step: 1, message: { + id: 'orphan', role: 'tool', toolCallId: 'missing', source: { kind: 'tool', callId: 'missing' }, + content: [{ type: 'text', text: 'orphan result' }], + } }, + }]) + const original = await observe(path) + const ctx = await mount(compression) + await expectCurrentRefusal(ctx, access, path, 'corruption', 'advertised tool lifecycle') + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it.each([false, true])('reopens native matching checkpoints with unfinished tail=%s without changing records', async (unfinished) => { + const rows = nativeCheckpoint('owner') + const path = await store(SESSION_FORMAT_VERSION, compression, unfinished ? rows.slice(0, 8) : rows) + const original = await observe(path) + const ctx = await mount(compression) + const handle = await ctx.sessionPersistence.open(id, access) + try { + const restored = await handle.read() + expect(restored.events.find(event => event.type === 'user/message' && event.data.id === 'checkpoint')?.data) + .toMatchObject({ source: { ...checkpointSource(), compactionId: 'owner' } }) + } finally { + await handle.close() + } + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it('leaves the V3 source unchanged when nested results are unsupported', async () => { + const rows = releasedToolRows({}, { content: [ + { type: 'tool-result', toolCallId: 'nested-call', isError: true, content: [{ type: 'text', text: 'inner failure' }] }, + ] }) + const path = await store(3, compression, rows) + const original = await observe(path) + const ctx = await mount(compression) + await expectRefusal(ctx, access, path, + 'format v3 tool/result at seq 7 contains a nested tool-result unsupported by this converter' + + '; source v3 artifact remains unchanged (raw log: ' + path + ')') + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations([path]) + }) + + it.each([ + { owner: 'result', field: 'extension', value: { saved: true } }, + { owner: 'result', field: '__proto__', value: { saved: true } }, + { owner: 'result', field: 'constructor', value: { saved: true } }, + { owner: 'message', field: 'toolCallId', value: 'conflicting-call' }, + { owner: 'message', field: 'isError', value: true }, + ] as const)('preserves $owner-owned $field through migration and native reopening', async ({ owner, field, value }) => { + const extra = Object.fromEntries([[field, value]]) + const rows = owner === 'message' ? releasedToolRows(extra) : releasedToolRows({}, extra) + const path = await store(3, compression, rows) + const original = await observe(path) + const ctx = await mount(compression) + for (const mode of [access, 'read'] as const) { + const handle = await ctx.sessionPersistence.open(id, mode) + try { + const result = (await handle.read()).events.find(event => event.type === 'tool/result') + expect(result?.data.message).toMatchObject({ + role: 'tool', toolCallId: 'outer-call', isError: false, + [`plugin:${owner}:${field}`]: value, + }) + expect(Object.hasOwn(result!.data.message, `plugin:${owner}:${field}`)).toBe(true) + } finally { + await handle.close() + } + } + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations(access === 'read' ? [path] : [path, generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression)]) + }) + + it('preserves outer V3 tool-message metadata through migration and native reopening', async () => { + const metadata = JSON.parse('{"__proto__":{"saved":"prototype"},"constructor":{"saved":"constructor"},"extension":{"saved":true}}') as SessionFormatJsonObject + const path = await store(3, compression, releasedToolRows({ ...metadata, toolCallId: 'outer-call', isError: false })) + const original = await observe(path) + const ctx = await mount(compression) + const expected = { + id: 'result', role: 'tool', source: { kind: 'tool', callId: 'outer-call' }, + toolCallId: 'outer-call', isError: false, content: [{ type: 'text', text: 'result' }], + 'plugin:message:toolCallId': 'outer-call', 'plugin:message:isError': false, + 'plugin:message:__proto__': metadata['__proto__'], 'plugin:message:constructor': metadata['constructor'], + 'plugin:message:extension': metadata['extension'], + } + for (const mode of [access, 'read'] as const) { + const handle = await ctx.sessionPersistence.open(id, mode) + try { + const restored = await handle.read() + const result = restored.events.find(event => event.type === 'tool/result') + expect(result?.data.message).toEqual(expected) + expect(Object.hasOwn(result!.data.message, 'plugin:message:__proto__')).toBe(true) + expect(Object.getPrototypeOf(result!.data.message)).toBe(Object.prototype) + } finally { + await handle.close() + } + } + expect(await observe(path)).toEqual(original) + await expectOnlyGenerations(access === 'read' ? [path] : [path, generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression)]) + }) + + it.each(nativeRefusals.flatMap(refusal => ([3, SESSION_FORMAT_VERSION] as const).map(version => ({ ...refusal, version }))))( + 'refuses V$version $name instead of falling back to readable V2', async ({ tail, diagnostic, currentError, currentSubject, version }) => { + const lowerPath = await store(2, compression, prefix) + const lower = await observe(lowerPath) + const ctx = await mount(compression) + const reader = await ctx.sessionPersistence.open(id, 'read') + try { + expect(reader.header.version).toBe(SESSION_FORMAT_VERSION) + const restored = await reader.read() + expect(restored.events.map(event => event.type)).toEqual([ + 'turn/start', 'step/start', 'system/message', 'user/message', 'system/message', 'request/header', + ]) + expect(restored.events.find(event => event.type === 'user/message')?.data).toEqual(question) + } finally { + await reader.close() + } + expect(await observe(lowerPath)).toEqual(lower) + await expectOnlyGenerations([lowerPath]) + + const path = await store(version, compression, [...(version === 3 ? releasedPrefix : nativePrefix), tail]) + const original = await observe(path) + for (let attempt = 0; attempt < 2; attempt += 1) { + if (version === 3) { + await expectRefusal(ctx, access, path, + diagnostic + `; source v${version} artifact remains unchanged (raw log: ${path})`) + } else { + await expectCurrentRefusal(ctx, access, path, currentError, currentSubject) + } + expect(await observe(path)).toEqual(original) + expect(await observe(lowerPath)).toEqual(lower) + await expectOnlyGenerations([lowerPath, path]) + } + }, + ) }) diff --git a/packages/session/session-persistence-jsonl/tests/multi-edge-publication.spec.ts b/packages/session/session-persistence-jsonl/tests/multi-edge-publication.spec.ts index 9be35ec1bf..b081b39d73 100644 --- a/packages/session/session-persistence-jsonl/tests/multi-edge-publication.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/multi-edge-publication.spec.ts @@ -1,7 +1,7 @@ /** Durable composition of historical chunk collapse and V3 system/reference migration. */ import { Context } from '@deepseek-ai/cordis' -import { Session, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, Session, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' import { createSessionFormatCatalog } from '@deepseek-ai/dsh-session-format' import { releasedV0SessionFormatCodec, releasedV1SessionFormatCodec, sessionFormatV0ToV1 } from '@deepseek-ai/dsh-session-format-v0-to-v1' @@ -150,7 +150,7 @@ function assertRequests(events: readonly SessionEvent[], header: SessionHeader) function assertMigrated(result: Awaited>) { const { events, header, cut, session } = result - expect(header).toEqual({ version: 3, id, createdAt: 1, parentSession: 'parent', delegationDepth: 0, isSeeded: true }) + expect(header).toEqual({ version: SESSION_FORMAT_VERSION, id, createdAt: 1, parentSession: 'parent', delegationDepth: 0, isSeeded: true }) expect(events.map(event => event.seq)).toEqual(Array.from({ length: 23 }, (_, seq) => seq)) expect(events.filter(event => event.type.startsWith('assistant/'))).toEqual([{ type: 'assistant/message', seq: 6, time: 108, surfaceOp: 'append', @@ -200,7 +200,7 @@ async function publishedRows(path: string, compression: JsonlCompression) { } describe.each([0, 1] as const)('V%s multi-edge durable publication', (version) => { - it.each(['none', 'zstd'] as const)('publishes only V3 after chunk collapse, system changes, and reference remapping (%s)', async (compression) => { + it.each(['none', 'zstd'] as const)('publishes only the current generation after chunk collapse, system changes, and reference remapping (%s)', async (compression) => { const { root, path } = await seed(version, compression) const source = await observe(path) const ctx = await mount(root, compression) @@ -215,7 +215,7 @@ describe.each([0, 1] as const)('V%s multi-edge durable publication', (version) = expect(written.events).toEqual(prepared.events) await ctx.fiber.dispose() contexts.splice(contexts.indexOf(ctx), 1) - const successor = generationLogPath(root, undefined, id, 3, compression) + const successor = generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression) expect((await readdir(dirname(path))).filter(name => name !== 'session.lock').sort()) .toEqual([basename(path), basename(successor)].sort()) expect(await publishedRows(successor, compression)).toEqual([{ type: 'session', ...prepared.header }, ...prepared.events]) @@ -263,7 +263,7 @@ describe.each([0, 1] as const)('V%s multi-edge durable publication', (version) = expect(retried.events).toEqual(expected) expect(retried.cut).toBe(prepared.cut) assertRequests(retried.events, retried.header) - const successor = generationLogPath(root, undefined, id, 3, compression) + const successor = generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression) expect(await publishedRows(successor, compression)).toEqual([{ type: 'session', ...prepared.header }, ...expected]) expect((await readdir(dirname(path))).filter(name => name !== 'session.lock').sort()) .toEqual([basename(path), basename(successor)].sort()) diff --git a/packages/session/session-persistence-jsonl/tests/native-developer-admission.spec.ts b/packages/session/session-persistence-jsonl/tests/native-developer-admission.spec.ts new file mode 100644 index 0000000000..a067941a8f --- /dev/null +++ b/packages/session/session-persistence-jsonl/tests/native-developer-admission.spec.ts @@ -0,0 +1,114 @@ +/** Native JSONL reads enforce developer relationships before exposing stored data. */ +import { Context } from '@deepseek-ai/cordis' +import { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' +import { SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { describe, expect, it, onTestFinished } from 'vitest' +import { generationLogPath } from '../src/format.ts' +import { compressZstdFrame } from '../src/zstd.ts' + +const id = SessionId('native-developer-admission') +const modes = (['none', 'zstd'] as const).flatMap(compression => (['read', 'write'] as const).map(access => ({ compression, access }))) +const coordinates = { turn: 1, step: 1 } +const developer = { type: 'developer/message', surfaceOp: 'append', data: { + ...coordinates, message: { id: 'developer', role: 'developer', source: { kind: 'tool-registry' }, content: [], extra: { retained: true } }, +} } + +describe.each(modes)('native developer admission ($compression, $access)', ({ compression, access }) => { + async function stored(event: object, corruptPrefix = false) { + const root = await mkdtemp(join(tmpdir(), 'dsh-native-developer-')) + const ctx = new Context() + onTestFinished(async () => { + try { + await ctx.fiber.dispose() + } finally { + await rm(root, { recursive: true, force: true }) + } + }) + const events = [ + { type: 'turn/start', data: { turn: 1 } }, + { type: 'step/start', data: coordinates }, + { type: 'system/message', surfaceOp: 'append', data: { + ...coordinates, message: { id: 'system', role: 'system', source: { kind: 'system-prompt' }, content: [{ type: 'text', text: 'System' }] }, + } }, + { type: 'request/header', data: { reason: 'initial', header: { config: { provider: 'test', model: 'test' }, tools: [{ name: 'search', description: 'Historical', parameters: {} }] } } }, + event, + ].map((row, seq) => ({ ...row, seq, time: seq + 1 })) + const header = { type: 'session', version: SESSION_FORMAT_VERSION, id, createdAt: 1, delegationDepth: 0, isSeeded: false } + const lines = [header, ...events].map(value => JSON.stringify(value) + '\n') + if (corruptPrefix) lines.splice(-1, 0, '{invalid json}\n') + const bytes = compression === 'none' ? Buffer.from(lines.join('')) : Buffer.concat(await Promise.all(lines.map(compressZstdFrame))) + const path = generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, bytes) + await ctx.plugin(JsonlSessionPersistence, { root, compression }) + return { ctx, path, bytes, events } + } + + it.each([false, true])('preserves an empty developer node and additional metadata on a valid open step (ignorable: %s)', async (ignorable) => { + const { ctx, path, bytes, events } = await stored({ ...developer, ...(ignorable ? { ignorable: true } : {}) }) + const handle = await ctx.sessionPersistence.open(id, access) + try { + expect((await handle.read()).events).toEqual(events) + } finally { + await handle.close() + } + expect(await readFile(path)).toEqual(bytes) + }) + + + it('reads name-only additions bound to their historical header without copying definitions', async () => { + const event = { ...developer, data: { ...developer.data, headerSeq: 3, message: { + ...developer.data.message, content: [{ type: 'tool-removal', toolName: 'old' }, { type: 'tool-addition', toolName: 'search' }], + } } } + const { ctx, path, bytes, events } = await stored(event) + const handle = await ctx.sessionPersistence.open(id, access) + try { + expect((await handle.read()).events).toEqual(events) + } finally { + await handle.close() + } + expect(await readFile(path)).toEqual(bytes) + }) + + it.each([ + { headerSeq: 0, toolName: 'search', error: /earlier request\/header/ }, + { headerSeq: 4, toolName: 'search', error: /must name an earlier event/ }, + { headerSeq: 3, toolName: 'absent', error: /exactly one tool/ }, + ])('refuses invalid historical schema binding %# without rewriting the generation', async ({ headerSeq, toolName, error }) => { + const event = { ...developer, data: { ...developer.data, headerSeq, message: { + ...developer.data.message, content: [{ type: 'tool-addition', toolName }], + } } } + const { ctx, path, bytes } = await stored(event) + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + await expect(opened).rejects.toThrow(error) + expect(await readFile(path)).toEqual(bytes) + }) + + it('refuses malformed known ignorable developer data even after a corrupt row', async () => { + const invalid = { ...developer, ignorable: true, data: { ...developer.data, message: { + ...developer.data.message, content: [{ type: 'tool-addition', toolName: 'search', tool: null }], + } } } + const { ctx, path, bytes } = await stored(invalid, true) + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + await expect(opened).rejects.toThrow('omit inline tool definitions') + expect(await readFile(path)).toEqual(bytes) + }) + + it.each([ + { name: 'mismatched step', event: { ...developer, data: { ...developer.data, step: 2 } }, error: /open.*step/ }, + { name: 'protected system head', event: { + ...developer, surfaceOp: { op: 'replace', startSeq: 2, endSeq: 2 }, sourceEventSeqs: [2], + }, error: /protected system head/ }, + ])('refuses a developer event with $name without rewriting the generation', async ({ event, error }) => { + const { ctx, path, bytes } = await stored(event) + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + await expect(opened).rejects.toBeInstanceOf(SessionPersistenceCorruptionError) + await expect(opened).rejects.toThrow(error) + expect(await readFile(path)).toEqual(bytes) + expect((await readdir(dirname(path))).filter(name => name !== 'session.lock')).toHaveLength(1) + }) +}) diff --git a/packages/session/session-persistence-jsonl/tests/native-source-admission.spec.ts b/packages/session/session-persistence-jsonl/tests/native-source-admission.spec.ts new file mode 100644 index 0000000000..4e9cf2c22b --- /dev/null +++ b/packages/session/session-persistence-jsonl/tests/native-source-admission.spec.ts @@ -0,0 +1,80 @@ +import { Context } from '@deepseek-ai/cordis' +import { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' +import { SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { generationLogPath } from '../src/format.ts' +import { compressZstdFrame } from '../src/zstd.ts' + +const id = SessionId('native-source-admission') +const modes = (['none', 'zstd'] as const).flatMap(compression => (['read', 'write'] as const).map(access => ({ compression, access }))) +let root: string +const contexts: Context[] = [] +beforeEach(async () => { root = await mkdtemp(join(tmpdir(), 'dsh-native-source-')) }) +afterEach(async () => { + try { + for (const ctx of contexts.splice(0).reverse()) await ctx.fiber.dispose() + } finally { + await rm(root, { recursive: true, force: true }) + } +}) + +describe.each(modes)('native message-source admission ($compression, $access)', ({ compression, access }) => { + async function stored(source: unknown, type = 'agent/inbox/spliced', ignorable = false) { + const header = { type: 'session', version: SESSION_FORMAT_VERSION, id, createdAt: 1, delegationDepth: 0, isSeeded: false } + const event = { type, seq: 0, time: 1, ...(ignorable ? { ignorable: true } : {}), data: { + target: 'next-turn', start: 0, inserted: [{ id: 'input', role: 'user', source, content: [{ type: 'text', text: 'queued' }] }], + } } + const lines = [header, event].map(value => JSON.stringify(value) + '\n') + const bytes = compression === 'none' ? Buffer.from(lines.join('')) : Buffer.concat(await Promise.all(lines.map(compressZstdFrame))) + const path = generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, compression) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, bytes) + const ctx = new Context() + contexts.push(ctx) + await ctx.plugin(JsonlSessionPersistence, { root, compression }) + return { ctx, path, bytes, event } + } + + it.each([null, {}, [], { kind: '' }, { kind: 1 }].map(source => ({ source })))('refuses malformed queued source $source before exposing a handle', async ({ source }) => { + const { ctx, path, bytes } = await stored(source) + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + await expect(opened).rejects.toBeInstanceOf(SessionPersistenceCorruptionError) + await expect(opened).rejects.toThrow('producer-owned source kind') + expect(await readFile(path)).toEqual(bytes) + expect((await readdir(dirname(path))).filter(name => name !== 'session.lock')).toHaveLength(1) + }) + + it('still validates known queued events marked ignorable', async () => { + const { ctx, path, bytes } = await stored({}, 'agent/inbox/spliced', true) + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + await expect(opened).rejects.toThrow('producer-owned source kind') + expect(await readFile(path)).toEqual(bytes) + }) + + it('preserves external attribution and own JSON metadata without a producer installed', async () => { + const source = JSON.parse('{"kind":"external-producer","__proto__":{"retain":true},"metadata":{"count":1}}') as unknown + const { ctx, path, bytes, event } = await stored(source) + const handle = await ctx.sessionPersistence.open(id, access) + try { + expect((await handle.read()).events[0]).toEqual(event) + } finally { + await handle.close() + } + expect(await readFile(path)).toEqual(bytes) + }) + + it('leaves unknown ignorable queued payloads opaque', async () => { + const { ctx, path, bytes, event } = await stored(null, 'external/inbox', true) + const handle = await ctx.sessionPersistence.open(id, access) + try { + expect((await handle.read()).events[0]).toEqual(event) + } finally { + await handle.close() + } + expect(await readFile(path)).toEqual(bytes) + }) +}) diff --git a/packages/session/session-persistence-jsonl/tests/retired-content-admission.spec.ts b/packages/session/session-persistence-jsonl/tests/retired-content-admission.spec.ts new file mode 100644 index 0000000000..d46b759df3 --- /dev/null +++ b/packages/session/session-persistence-jsonl/tests/retired-content-admission.spec.ts @@ -0,0 +1,57 @@ +/** Interpreted retired content must fail before migration publication or recoverable native-tail suppression. */ +import { Context } from '@deepseek-ai/cordis' +import { SessionId } from '@deepseek-ai/dsh-session' +import { SessionFormatUnsupportedError, SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { basename, dirname, join } from 'node:path' +import { describe, expect, it, onTestFinished } from 'vitest' +import { generationLogPath } from '../src/format.ts' +import { compressZstdFrame } from '../src/zstd.ts' + +const id = SessionId('retired-content-admission') +const wrapper = { type: 'tool-result', toolCallId: 'retired-call', content: [{ type: 'text', text: 'result' }] } +const modes = (['none', 'zstd'] as const).flatMap(compression => + (['read', 'write'] as const).map(access => ({ compression, access }))) + +describe.each(modes)('retired content in JSONL ($compression, $access)', ({ compression, access }) => { + async function stored(version: 3 | 4, opaque: boolean, corruptPrefix: boolean) { + const root = await mkdtemp(join(tmpdir(), 'dsh-retired-content-')) + const ctx = new Context() + onTestFinished(async () => { + try { await ctx.fiber.dispose() } finally { await rm(root, { recursive: true, force: true }) } + }) + const event = { type: opaque ? 'future/opaque' : 'user/message', seq: 0, time: 1, + ...(opaque ? { ignorable: true } : { surfaceOp: 'append' }), + data: { id: 'user', role: 'user', source: { kind: 'user' }, content: [wrapper] }, + } + const header = { type: 'session', version, id, createdAt: 1, delegationDepth: 0, isSeeded: false } + const lines = [JSON.stringify(header) + '\n', ...(corruptPrefix ? ['{invalid json}\n'] : []), JSON.stringify(event) + '\n'] + const bytes = compression === 'none' ? Buffer.from(lines.join('')) + : Buffer.concat(await Promise.all(lines.map(compressZstdFrame))) + const path = generationLogPath(root, undefined, id, version, compression) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, bytes) + await ctx.plugin(JsonlSessionPersistence, { root, compression }) + return { ctx, path, bytes, event } + } + + it.each([{ version: 3, corruptPrefix: false }, { version: 4, corruptPrefix: false }, { version: 4, corruptPrefix: true }] as const) + ('refuses V$version content with corruptPrefix=$corruptPrefix and preserves the only generation', async ({ version, corruptPrefix }) => { + const { ctx, path, bytes } = await stored(version, false, corruptPrefix) + const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { await handle.close() }) + await expect(opened).rejects.toBeInstanceOf(version === 3 ? SessionFormatUnsupportedError : SessionPersistenceCorruptionError) + await expect(opened).rejects.toThrow(/released tool-result wrapper/) + expect(await readFile(path)).toEqual(bytes) + expect((await readdir(dirname(path))).filter(name => name !== 'session.lock')).toEqual([basename(path)]) + }) + + it.each([3, 4] as const)('preserves an unknown ignorable V%s payload without interpreting its content', async (version) => { + const { ctx, path, bytes, event } = await stored(version, true, false) + const handle = await ctx.sessionPersistence.open(id, access) + const expected = version === 3 ? { ...event, type: 'plugin:future/opaque' } : event + try { expect((await handle.read()).events).toEqual([expected]) } finally { await handle.close() } + expect(await readFile(path)).toEqual(bytes) + }) +}) diff --git a/packages/session/session-persistence-jsonl/tests/v2-ptc-migration.spec.ts b/packages/session/session-persistence-jsonl/tests/v2-ptc-migration.spec.ts index e22acf4aef..773d4754df 100644 --- a/packages/session/session-persistence-jsonl/tests/v2-ptc-migration.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/v2-ptc-migration.spec.ts @@ -1,7 +1,7 @@ /** Real JSONL publication and provider-neutral message preservation across the V2 PTC rename. */ import { Context } from '@deepseek-ai/cordis' -import { Session, SessionId } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, Session, SessionId } from '@deepseek-ai/dsh-session' import type { SessionFormatEvent } from '@deepseek-ai/dsh-session-format' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' import { createHash } from 'node:crypto' @@ -40,6 +40,10 @@ const toolMessage = { content: [{ type: 'text', text: 'tools-code-mode: image attached; tool/code-dispatch' }], }], } +const currentToolMessage = { + role: 'tool', source: toolMessage.source, toolCallId: toolCall.id, + content: toolMessage.content[0]!.content, isError: false, id: toolMessage.id, +} const imageMessage = { id: 'tools-code-mode:root-call:image-context', role: 'user', source: { kind: 'plugin', plugin: 'tools-code-mode', form: 'notice', summary: 'Image from tools-code-mode' }, @@ -53,7 +57,8 @@ const imageMessage = { ], } const currentImageMessage = { - ...imageMessage, source: { ...imageMessage.source, plugin: 'tools-ptc' }, + ...imageMessage, + source: { kind: 'ptc-mode', form: imageMessage.source.form, summary: imageMessage.source.summary }, } const dispatch = { rootCallId: toolCall.id, parentCallId: toolCall.id, subCallId: 'tools-code-mode:child-call', @@ -117,21 +122,21 @@ describe('JSONL V2 PTC publication and restore', () => { } }) - it('publishes V3 without changing V2 bytes and preserves restored IDs, roles, content, and replay state', async () => { + it('publishes the current generation without changing V2 bytes and preserves restored IDs, roles, content, and replay state', async () => { if (root === undefined || ctx === undefined) throw new Error('persistence fixture is not initialized') const id = SessionId('tools-code-mode:session') const header = { type: 'session', version: 2, id, createdAt: 1000, isSeeded: false, delegationDepth: 0 } const events = releasedV2Events() const source = Buffer.from([header, ...events].map(row => JSON.stringify(row)).join('\n') + '\n') const predecessor = generationLogPath(root, undefined, id, 2, 'none') - const successor = join(dirname(predecessor), 'session.v3.jsonl') + const successor = join(dirname(predecessor), `session.v${SESSION_FORMAT_VERSION}.jsonl`) await mkdir(dirname(predecessor), { recursive: true }) await writeFile(predecessor, source) const sourceStat = await stat(predecessor) const reader = await ctx.sessionPersistence.open(id, 'read') try { - expect(reader.header).toEqual({ version: 3, id, createdAt: 1000, isSeeded: false, delegationDepth: 0 }) + expect(reader.header).toEqual({ version: SESSION_FORMAT_VERSION, id, createdAt: 1000, isSeeded: false, delegationDepth: 0 }) expect((await reader.read()).events.map(event => event.type)).toEqual([ 'turn/start', 'step/start', 'system/message', 'user/message', 'assistant/message', 'tool/call', 'tool/ptc-dispatch-start', 'tool/ptc-dispatch', 'tool/result', 'agent/inbox/spliced', @@ -153,21 +158,26 @@ describe('JSONL V2 PTC publication and restore', () => { const published = await readFile(successor) const [publishedHeader, ...publishedEvents] = published.toString('utf8').trimEnd().split('\n') .map((row): unknown => JSON.parse(row)) - expect(publishedHeader).toEqual({ ...header, version: 3 }) + expect(publishedHeader).toEqual({ ...header, version: SESSION_FORMAT_VERSION }) const expectedEvents: SessionFormatEvent[] = events.map(event => ({ ...event, seq: event.seq < 2 ? event.seq : event.seq + 1 })) expectedEvents[5] = { ...expectedEvents[5], type: 'tool/ptc-dispatch-start' } as SessionFormatEvent expectedEvents[6] = { ...expectedEvents[6], type: 'tool/ptc-dispatch' } as SessionFormatEvent + expectedEvents[7] = { ...expectedEvents[7], data: { turn: 1, step: 1, message: currentToolMessage } } as SessionFormatEvent expectedEvents[8] = { ...expectedEvents[8], data: { target: 'next-step', start: 0, removedCount: 0, inserted: [currentImageMessage], } } as SessionFormatEvent expectedEvents[9] = { ...expectedEvents[9], data: currentImageMessage } as SessionFormatEvent + const titleRequestData = events[10]?.data as { messages: Array> } expectedEvents[10] = { ...expectedEvents[10], data: { ...(events[10]?.data as Record), messageSeqs: [3], + messages: titleRequestData.messages.map(message => ({ + ...message, source: { kind: 'dsh-session-title-llm' }, + })), } } as SessionFormatEvent const systemMessage = { id: 'v2-to-v3-system-' + createHash('sha256') .update(JSON.stringify(['session-format-v2-to-v3', id, 1, 'step/start'])).digest('hex'), - role: 'system', source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, content: [], + role: 'system', source: { kind: 'system-prompt' }, content: [], } expectedEvents.splice(2, 0, { type: 'system/message', seq: 2, time: 1002, surfaceOp: 'append', @@ -186,10 +196,10 @@ describe('JSONL V2 PTC publication and restore', () => { expect(restored.events).toEqual(expectedEvents) const session = Session.fromRestore(id, restored.events, reloaded.header, reloaded.inheritedEventCount, restored.eventState) const messages = session.deriveMessages() - expect(messages).toEqual([userMessage, assistantMessage, toolMessage, currentImageMessage]) + expect(messages).toEqual([userMessage, assistantMessage, currentToolMessage, currentImageMessage]) // Provider-neutral input evidence: no provider converter is a declared dependency here. expect(messages.map(({ id, role, content }) => ({ id, role, content }))).toEqual( - [userMessage, assistantMessage, toolMessage, imageMessage].map(({ id, role, content }) => ({ id, role, content })), + [userMessage, assistantMessage, currentToolMessage, imageMessage].map(({ id, role, content }) => ({ id, role, content })), ) expect(messages[1]?.source).toEqual(assistantMessage.source) expect(messages[2]?.source).toEqual({ kind: 'tool', callId: 'tools-code-mode:root-call' }) @@ -201,6 +211,6 @@ describe('JSONL V2 PTC publication and restore', () => { expect(await stat(predecessor)).toMatchObject({ dev: sourceStat.dev, ino: sourceStat.ino }) expect(await readFile(successor)).toEqual(published) expect((await readdir(dirname(predecessor))).filter(name => name.endsWith('.jsonl')).sort()) - .toEqual(['session.v2.jsonl', 'session.v3.jsonl']) + .toEqual(['session.v2.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) }) }) diff --git a/packages/session/session-persistence-jsonl/tests/v2-system-migration.spec.ts b/packages/session/session-persistence-jsonl/tests/v2-system-migration.spec.ts index b8a7fad132..416f04e3eb 100644 --- a/packages/session/session-persistence-jsonl/tests/v2-system-migration.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/v2-system-migration.spec.ts @@ -1,6 +1,6 @@ import { freezeMessage, MessageId } from '@deepseek-ai/dsh-llm' import { Context } from '@deepseek-ai/cordis' -import { Session, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' +import { SESSION_FORMAT_VERSION, Session, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import { SessionFormatUnsupportedError } from '@deepseek-ai/dsh-session-persistence' import type { SessionHandle } from '@deepseek-ai/dsh-session-persistence' @@ -95,7 +95,7 @@ function assertRequestHistory(events: readonly SessionEvent[], handle: SessionHa } describe('V2 system prompts through current Session and JSONL persistence', () => { - it.each([undefined, ''])('prepares prompts and clear (%j) read-only, then publishes V3 without replacing V2', async (clear) => { + it.each([undefined, ''])('prepares prompts and clear (%j) read-only, then publishes the current generation without replacing V2', async (clear) => { const sourcePath = await writeV2([ { type: 'turn/start', data: { turn: 1 } }, { type: 'step/start', data: { turn: 1, step: 1 } }, @@ -110,7 +110,7 @@ describe('V2 system prompts through current Session and JSONL persistence', () = const reader = await ctx.sessionPersistence.open(id, 'read') let prepared: readonly SessionEvent[] try { - expect(reader.header.version).toBe(3) + expect(reader.header.version).toBe(SESSION_FORMAT_VERSION) prepared = (await reader.read()).events expect(prepared.map(event => event.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) expect(prepared.filter(event => event.type !== 'system/message').map(event => [event.type, event.time])).toEqual([ @@ -156,10 +156,10 @@ describe('V2 system prompts through current Session and JSONL persistence', () = } expect(await observeFile(sourcePath)).toEqual(original) expect((await readdir(directory)).filter(name => name.endsWith('.jsonl')).sort()) - .toEqual(['session.v2.jsonl', 'session.v3.jsonl']) - const publishedPath = generationLogPath(root, undefined, id, 3, 'none') + .toEqual(['session.v2.jsonl', `session.v${SESSION_FORMAT_VERSION}.jsonl`]) + const publishedPath = generationLogPath(root, undefined, id, SESSION_FORMAT_VERSION, 'none') const published = (await readFile(publishedPath, 'utf8')).trimEnd().split('\n').map(line => JSON.parse(line) as unknown) - expect(published[0]).toMatchObject({ type: 'session', version: 3, id }) + expect(published[0]).toMatchObject({ type: 'session', version: SESSION_FORMAT_VERSION, id }) expect(published.slice(1)).toEqual(prepared) const reopened = await mount() @@ -223,7 +223,7 @@ describe('V2 system prompts through current Session and JSONL persistence', () = session.append('step/start', { turn: 2, step: 1 }) session.append('system/message', { turn: 2, step: 1, - message: freezeMessage({ role: 'system', id: MessageId('resumed-system'), content: [{ type: 'text', text: 'resumed prompt' }], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' } }), + message: freezeMessage({ role: 'system', id: MessageId('resumed-system'), content: [{ type: 'text', text: 'resumed prompt' }], source: { kind: 'system-prompt' } }), }, { surfaceOp: { op: 'replace', startSeq: SessionSeq(4), endSeq: SessionSeq(4) }, sourceEventSeqs: [SessionSeq(4)] }) session.append('step/end', { turn: 2, step: 1 }) session.append('turn/end', { turn: 2, reason: { kind: 'completed' } }) @@ -268,7 +268,7 @@ describe('V2 system prompts through current Session and JSONL persistence', () = .toEqual(['session.v1.jsonl', 'session.v2.jsonl']) }) - it('persists native V3 system appends after the protected head without converting them to user messages', async () => { + it('persists current system appends after the protected head without converting them to user messages', async () => { const ctx = await mount() const session = Session.create(id) const writer = await ctx.sessionPersistence.create(session.header) @@ -277,12 +277,12 @@ describe('V2 system prompts through current Session and JSONL persistence', () = session.append('step/start', { turn: 1, step: 1 }) session.append('system/message', { turn: 1, step: 1, - message: freezeMessage({ role: 'system', id: MessageId('head'), content: [{ type: 'text', text: 'head prompt' }], source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' } }), + message: freezeMessage({ role: 'system', id: MessageId('head'), content: [{ type: 'text', text: 'head prompt' }], source: { kind: 'system-prompt' } }), }, { surfaceOp: 'append' }) session.append('user/message', freezeMessage({ role: 'user', id: MessageId('question'), content: human.content, source: { kind: 'user' } }), { surfaceOp: 'append' }) session.append('system/message', { turn: 1, step: 1, - message: freezeMessage({ role: 'system', id: MessageId('context'), content: [{ type: 'text', text: 'tail context' }], source: { kind: 'plugin', plugin: 'context-plugin' } }), + message: freezeMessage({ role: 'system', id: MessageId('context'), content: [{ type: 'text', text: 'tail context' }], source: { kind: 'system-prompt' } }), }, { surfaceOp: 'append' }) session.append('step/end', { turn: 1, step: 1 }) session.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) diff --git a/packages/session/session-persistence-jsonl/tests/v3-event-admission.spec.ts b/packages/session/session-persistence-jsonl/tests/v3-event-admission.spec.ts deleted file mode 100644 index 02e9d8aef7..0000000000 --- a/packages/session/session-persistence-jsonl/tests/v3-event-admission.spec.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Context } from '@deepseek-ai/cordis' -import { SessionId, SessionSeq } from '@deepseek-ai/dsh-session' -import { SessionFormatUnsupportedError } from '@deepseek-ai/dsh-session-persistence' -import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' -import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { dirname, join } from 'node:path' -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { generationLogPath, scanLog } from '../src/format.ts' - -const id = SessionId('v3-admission') -const header = { type: 'session', version: 3, id, createdAt: 1000, isSeeded: false, delegationDepth: 0 } -const start = { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } } -const prefix = [header, start].map(row => JSON.stringify(row)).join('\n') + '\n' -const obsoleteTypes = ['tool/code-dispatch-start', 'tool/code-dispatch'] as const - -function obsoleteEvent(type: string, ignorable?: true) { - return { - type, seq: 1, time: 2, - data: { rootCallId: 'root', parentCallId: 'root', subCallId: 'child', name: 'read', arguments: {} }, - ...(ignorable ? { ignorable } : {}), - } -} - -describe('native V3 event admission at EOF', () => { - let root: string - let ctx: Context - - beforeEach(async () => { - root = await mkdtemp(join(tmpdir(), 'dsh-v3-admission-')) - ctx = new Context() - await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' }) - }) - - afterEach(async () => { - try { - await ctx?.fiber.dispose() - } finally { - if (root !== undefined) await rm(root, { recursive: true, force: true }) - } - }) - - async function store(bytes: Buffer): Promise { - const path = generationLogPath(root, undefined, id, 3, 'none') - await mkdir(dirname(path), { recursive: true }) - await writeFile(path, bytes) - return path - } - - it.each([{ surfaceOp: 'append' }, { sourceEventSeqs: [] }])('refuses unknown required metadata %j without truncating a provider append', async (metadata) => { - const event = { type: 'future/required', seq: 0, time: 1, data: {}, ...metadata } - const bytes = Buffer.from([header, event].map(row => JSON.stringify(row)).join('\n') + '\n') - expect(scanLog(bytes)).toMatchObject({ events: [event], committedBytes: bytes.length }) - const path = await store(bytes) - const sourceStat = await stat(path) - for (const access of ['read', 'write'] as const) { - const operation = async () => { - const handle = await ctx.sessionPersistence.open(id, access) - try { - if (access === 'read') await handle.read() - else await handle.append([{ type: 'turn/start', seq: SessionSeq(1), time: 2, data: { turn: 1 } }]) - } finally { - await handle.close() - } - } - await expect(operation()).rejects.toThrow('unknown to this harness and not marked ignorable') - expect(await readFile(path)).toEqual(bytes) - expect(await stat(path)).toMatchObject({ dev: sourceStat.dev, ino: sourceStat.ino }) - } - }) - - it.each(obsoleteTypes)('scanLog refuses a complete required %s EOF row', (type) => { - const bytes = Buffer.from(prefix + JSON.stringify(obsoleteEvent(type)) + '\n') - expect(() => scanLog(bytes)).toThrow(SessionFormatUnsupportedError) - expect(() => scanLog(bytes)).toThrow('format v3 contains unknown event type') - }) - - it.each(obsoleteTypes.flatMap(type => ['', '{not json\n', 'null\n'].map(corruption => ({ type, corruption }))))( - 'scan, read and write refuse required $type after "$corruption" without changing bytes or inode', async ({ type, corruption }) => { - const bytes = Buffer.from(prefix + corruption + JSON.stringify(obsoleteEvent(type)) + '\n') - expect(() => scanLog(bytes)).toThrow(SessionFormatUnsupportedError) - expect(() => scanLog(bytes)).toThrow('format v3 contains unknown event type') - const path = await store(bytes) - const sourceStat = await stat(path) - for (const access of ['read', 'write'] as const) { - const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { - await handle.close() - }) - await expect(opened).rejects.toThrow(SessionFormatUnsupportedError) - expect(await readFile(path)).toEqual(bytes) - expect(await stat(path)).toMatchObject({ dev: sourceStat.dev, ino: sourceStat.ino }) - } - }, - ) - - it.each(['', '{not json\n', 'null\n'])('refuses malformed system payloads after %j without modifying storage', async (corruption) => { - const malformed = { type: 'system/message', seq: 1, time: 2, data: null, surfaceOp: 'append' } - const bytes = Buffer.from(prefix + corruption + JSON.stringify(malformed) + '\n') - expect(() => scanLog(bytes)).toThrow('system/message data must be an object') - const path = await store(bytes) - const sourceStat = await stat(path) - for (const access of ['read', 'write'] as const) { - const opened = ctx.sessionPersistence.open(id, access).then(async (handle) => { - await handle.close() - }) - await expect(opened).rejects.toThrow('system/message data must be an object') - expect(await readFile(path)).toEqual(bytes) - expect(await stat(path)).toMatchObject({ dev: sourceStat.dev, ino: sourceStat.ino }) - } - }) - - it.each(obsoleteTypes)('retains ignorable %s through scanning and a provider append', async (type) => { - const event = obsoleteEvent(type, true) - const bytes = Buffer.from(prefix + JSON.stringify(event) + '\n') - expect(scanLog(bytes)).toMatchObject({ events: [start, event], committedBytes: bytes.length }) - const path = await store(bytes) - const writer = await ctx.sessionPersistence.open(id, 'write') - try { - expect((await writer.read()).events).toEqual([start, event]) - await writer.append([{ - type: 'turn/end', seq: SessionSeq(2), time: 3, data: { turn: 1, reason: { kind: 'completed' } }, - }]) - } finally { - await writer.close() - } - expect((await readFile(path)).subarray(0, bytes.length)).toEqual(bytes) - }) - - it.each([ - '{not json', - 'null', - JSON.stringify({ type: 'user/message', seq: 1, time: 2, data: { - id: 'missing-surface-op', role: 'user', content: [{ type: 'text', text: 'malformed canonical tail' }], - } }), - ])('still recovers an ordinary malformed EOF row: %s', async (tail) => { - const bytes = Buffer.from(prefix + tail + '\n') - expect(scanLog(bytes)).toMatchObject({ events: [start], committedBytes: Buffer.byteLength(prefix) }) - const path = await store(bytes) - const writer = await ctx.sessionPersistence.open(id, 'write') - const end = { - type: 'turn/end' as const, seq: SessionSeq(1), time: 3, data: { turn: 1, reason: { kind: 'completed' as const } }, - } - try { - expect((await writer.read()).events).toEqual([start]) - await writer.append([end]) - } finally { - await writer.close() - } - expect(await readFile(path, 'utf8')).toBe(prefix + JSON.stringify(end) + '\n') - }) -}) diff --git a/packages/session/session-persistence-jsonl/tests/zstd.spec.ts b/packages/session/session-persistence-jsonl/tests/zstd.spec.ts index 222ffbb3bd..4ec279ac61 100644 --- a/packages/session/session-persistence-jsonl/tests/zstd.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/zstd.spec.ts @@ -440,7 +440,7 @@ describe('JsonlSessionPersistence: default Zstandard encoding', () => { turn: 1, step: 1, message: { id: 'v2-to-v3-system-fc06c3f7720f3bc94ea7a2b7fadde6a5b100c6ab6ca342d2222bd017184a0b67', - role: 'system', source: { kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }, content: [], + role: 'system', source: { kind: 'system-prompt' }, content: [], }, }, }, diff --git a/packages/session/session-persistence-jsonl/tsconfig.json b/packages/session/session-persistence-jsonl/tsconfig.json index 393ada381f..d3484120a6 100644 --- a/packages/session/session-persistence-jsonl/tsconfig.json +++ b/packages/session/session-persistence-jsonl/tsconfig.json @@ -36,7 +36,7 @@ "path": "../session-format-catalog" }, { - "path": "../session-format-v2-to-v3" + "path": "../session-format-v3-to-v4" } ] } diff --git a/packages/session/session-projection-cache/README.i18n.yaml b/packages/session/session-projection-cache/README.i18n.yaml index 6b96623f7e..9945e2d6dd 100644 --- a/packages/session/session-projection-cache/README.i18n.yaml +++ b/packages/session/session-projection-cache/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/session/session-projection-cache/README.md -README.md: 3125f50b07f222feb0ef2af5e28abcfae19631a7 -README.zh.md: c98cda187dd898a0b30a9721c0bc7412a91964c5 +README.md: 0417601210b697983993f770688a4e944d518790 +README.zh.md: 32dcbd93c8f18e504ca3a350586860b2e5cbd5b6 diff --git a/packages/session/session-projection-cache/README.md b/packages/session/session-projection-cache/README.md index 3125f50b07..0417601210 100644 --- a/packages/session/session-projection-cache/README.md +++ b/packages/session/session-projection-cache/README.md @@ -62,7 +62,7 @@ Three mandatory points always write: session creation persists the seed-derived ### What the cache guarantees -The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`formatVersion`, `createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row folded from another Session format generation or fork cut cannot seed the caller. The JSON backend stores each record at `/session_projcache/sessions/.json` in an owner-only directory tree. +The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`formatVersion`, `createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row folded from another Session format generation or fork cut cannot seed the caller. The JSON backend stores each record at `/session_projcache/sessions/.json` in an owner-only directory tree. Domain read validation preserves every own JSON key in checkpoint values, including `__proto__` and `constructor` inside opaque metadata. It rejects values that cannot survive a lossless JSON round trip, using the same rules as checkpoint writes. Each projection then validates its hydration state with its own `stateSchema`; fields carrying opaque JSON need a validator that preserves their keys. Upgrades never block startup or expose an unproven fold. Records stamped with a version in the spec's `compatibleVersions` remain structurally readable for a current checkpoint rewrite, but a missing or older `formatVersion` never matches a current Session and therefore cannot seed hydration. A lifecycle-matching predecessor title remains available only through the listing hint above because title text is invariant across the adjacent Session-format edges and its row still passes the current projection `stateVersion` and schema. Once the format matches, absent lineage fields decode as the unseeded lineage — exact for unseeded sessions, while a seeded caller fails the identity match and refolds cold. A stored record that still fails schema validation is moved aside as `.json.bak.` under the domain's `invalidRecords: 'backup-and-skip'` policy, logged with its cause, and rebuilt by the next checkpoint. diff --git a/packages/session/session-projection-cache/README.zh.md b/packages/session/session-projection-cache/README.zh.md index c98cda187d..32dcbd93c8 100644 --- a/packages/session/session-projection-cache/README.zh.md +++ b/packages/session/session-projection-cache/README.zh.md @@ -62,7 +62,7 @@ kind: "package-reference" ### 缓存保证什么 -日志领先,缓存跟随:活会话检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配当前运行单元的 schema 与完整生命周期身份(`formatVersion`、`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此从另一会话格式代或 fork 切点折叠出的行不能播种调用方。JSON 后端把每条记录存于仅所有者可访问的 `/session_projcache/sessions/.json` 目录树中。 +日志领先,缓存跟随:活会话检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配当前运行单元的 schema 与完整生命周期身份(`formatVersion`、`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此从另一会话格式代或 fork 切点折叠出的行不能播种调用方。JSON 后端把每条记录存于仅所有者可访问的 `/session_projcache/sessions/.json` 目录树中。Domain 读取校验保留检查点值中的所有自有 JSON 键,包括不透明元数据中的 `__proto__` 与 `constructor`。它拒绝无法无损完成 JSON 往返的值,并与检查点写入使用相同规则。随后,每个 projection 用自己的 `stateSchema` 校验 hydration 状态;承载不透明 JSON 的字段需要使用保留其键的校验器。 升级绝不拖垮启动,也不会暴露未经证明的折叠结果。版本戳落在 spec `compatibleVersions` 集合内的记录仍可被结构化读取并等待当前检查点重写,但缺失或更旧的 `formatVersion` 绝不匹配当前 Session,因此不能作为 hydrate seed。生命周期匹配的 predecessor title 只能通过上述列表 hint 读取,因为 title 文本在相邻 Session format edge 之间保持不变,并且该 row 仍须通过当前 projection `stateVersion` 与 schema。格式匹配后,缺失的 lineage 字段解码为 unseeded lineage——对非 fork 会话精确无误,seeded 调用方则通不过身份比对、回落冷折叠。仍然通不过 schema 校验的存量记录会按域的 `invalidRecords: 'backup-and-skip'` 策略移出为 `.json.bak.<时间戳>`、连同原因写入日志,并由下一次检查点重建。 diff --git a/packages/session/session-projection-cache/src/spec.ts b/packages/session/session-projection-cache/src/spec.ts index a94ed5a493..c8bcda38b8 100644 --- a/packages/session/session-projection-cache/src/spec.ts +++ b/packages/session/session-projection-cache/src/spec.ts @@ -11,6 +11,8 @@ */ import { z } from 'zod' +import { isJsonValue } from '@deepseek-ai/dsh-util-values' +import type { JsonValue } from '@deepseek-ai/dsh-util-values' import { SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { SessionId, SessionSeqCursor } from '@deepseek-ai/dsh-session' import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain' @@ -18,16 +20,17 @@ import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain' /** * One persisted checkpoint row (the RFC's `(sessionId, key, ver, seq, val)` * minus the two record keys). `val` is the unit's internal state — plain - * JSON by the unit contract; `z.json()` enforces that at the durable - * boundary. A row is never wrong, only possibly stale: `seq` says exactly - * how stale, and a `ver` mismatch against the live unit's `stateVersion` + * JSON by the unit contract. Validation uses the same lossless JSON rules as + * writes and preserves every state key without cloning. A row is never wrong, + * only possibly stale: `seq` says exactly how stale, and a `ver` mismatch + * against the live unit's `stateVersion` * discards it at read time (never a migration). */ export const checkpointRow = z.object({ ver: z.number().int().nonnegative(), seq: z.number().int().gte(-1).transform((value): SessionSeqCursor => value === -1 ? -1 : SessionSeq(value)), - val: z.json(), + val: z.custom(isJsonValue, { message: 'checkpoint state must be losslessly JSON-serializable' }), }) /** diff --git a/packages/session/session-projection-cache/tests/fixtures.spec.ts b/packages/session/session-projection-cache/tests/fixtures.spec.ts index 4377fadcf2..3b3de927d6 100644 --- a/packages/session/session-projection-cache/tests/fixtures.spec.ts +++ b/packages/session/session-projection-cache/tests/fixtures.spec.ts @@ -1,15 +1,16 @@ /** - * Cross-version recovery over archived on-disk artifacts. `fixtures/` holds - * real `session_projcache` media, each produced by driving the named release - * through its own web app (session created over RPC, real model turns, a - * rename): the v3 whole-unit file (published 0.1.1-rc.2), a v4 per-record + * Cross-version recovery and lossless checkpoint JSON validation. The released + * `session_projcache` fixtures were captured through their own web app + * (session created over RPC, real model turns, a rename): the v3 whole-unit + * file (published 0.1.1-rc.2), a v4 per-record * document (published 0.1.2-alpha.3), a published v5 document, and the * v5-stamped lineage-less document reproducing byte-for-byte what the * formerly unguarded legacy bootstrap wrote over v3 records. Each must open * through the real storage stack without becoming a fold shortcut for the * current Session format, then accept a current checkpoint rewrite. A record * that fails schema validation is backed up and skipped instead of failing the - * boot. + * boot. The synthetic V7 fixture comes from the real StorageDomain per-record + * writer and contains opaque keys and arrays, independent of Session messages. */ import { afterEach, describe, expect, it, vi } from 'vitest' @@ -31,7 +32,7 @@ import { apply as storageDomainApply, Config as storageDomainConfig, inject as storageDomainInject, name as storageDomainName, } from '@deepseek-ai/dsh-storage-domain' import SessionProjectionCache from '../src/index.ts' -import { projectionCacheDomainSpec } from '../src/spec.ts' +import { checkpointRow, projectionCacheDomainSpec } from '../src/spec.ts' // Declarations must match the shipped title unit's exactly (the repo-wide // compile face sees both). @@ -95,13 +96,18 @@ function headerFor(id: SessionId, identity: FixtureDoc['record']['identity']): S const contexts: Context[] = [] const roots: string[] = [] -async function harness(root: string) { - roots.push(root) +async function storageHarness(root: string) { + if (!roots.includes(root)) roots.push(root) const ctx = new Context() contexts.push(ctx) await ctx.plugin(Storage) await ctx.plugin({ name: storageJsonName, inject: storageJsonInject, apply: storageJsonApply, Config: storageJsonConfig }, { root }) await ctx.plugin({ name: storageDomainName, inject: storageDomainInject, apply: storageDomainApply, Config: storageDomainConfig }, { backend: 'json' }) + return ctx +} + +async function harness(root: string) { + const ctx = await storageHarness(root) await ctx.plugin(SessionStore) await ctx.plugin(SessionProjectionRegistry) ctx.sessionProjections.register(titleUnit) @@ -144,6 +150,50 @@ afterEach(async () => { await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }))) }) +describe('checkpoint JSON preservation', () => { + it('preserves opaque keys through StorageDomain read, put, and reopen', async () => { + const root = await mkdtemp(join(tmpdir(), 'dsh-projcache-opaque-')) + const id = SessionId('opaque-fixture') + const archived = await placeDoc(root, id, 'v7-opaque-session-doc.json') + expect(archived.version).toBe(7) + const ctx = await storageHarness(root) + const domain = await ctx.storageDomain.open(projectionCacheDomainSpec) + const record = domain.table('sessions').get(id)! + expect(JSON.stringify(record.rows)).toBe(JSON.stringify(archived.record.rows)) + const rewritten = { ...record, identity: { ...record.identity, formatVersion: SESSION_FORMAT_VERSION } } + await domain.table('sessions').put(id, rewritten) + await ctx.fiber.dispose() + contexts.splice(contexts.indexOf(ctx), 1) + + const reopenedCtx = await storageHarness(root) + const reopened = await reopenedCtx.storageDomain.open(projectionCacheDomainSpec) + const restored = reopened.table('sessions').get(id)! + expect(JSON.stringify(restored)).toBe(JSON.stringify(rewritten)) + expect(JSON.stringify(restored.rows)).toBe(JSON.stringify(archived.record.rows)) + const onDisk = JSON.parse(await readFile(join(root, projectionCacheDomainSpec.name, 'sessions', `${id}.json`), 'utf8')) as FixtureDoc + expect(onDisk.version).toBe(7) + expect(JSON.stringify(onDisk.record.rows)).toBe(JSON.stringify(archived.record.rows)) + }) + + it.each([ + ['undefined', undefined], ['function', () => {}], ['symbol', Symbol('opaque')], ['bigint', 1n], + ['nonfinite number', Number.NaN], ['infinity', Number.POSITIVE_INFINITY], + ['class instance', new Date(0)], ['map', new Map([['saved', true]])], + ])('rejects non-JSON checkpoint state: %s', (_name, val) => { + expect(checkpointRow.safeParse({ ver: 1, seq: 0, val }).success).toBe(false) + }) + + it('rejects cycles and JSON-lossy nested values without changing valid state objects', () => { + const cyclic: { self?: unknown } = {} + cyclic.self = cyclic + for (const val of [cyclic, { nested: { value: undefined } }, [undefined], [, 'hole'], { negativeZero: -0 }]) { + expect(() => checkpointRow.parse({ ver: 1, seq: 0, val })).toThrow() + } + const val = JSON.parse('{"__proto__":{"saved":true},"constructor":{"saved":false},"nested":{"__proto__":[null,true,4,"text"]}}') as Record + expect(checkpointRow.parse({ ver: 1, seq: 0, val }).val).toBe(val) + }) +}) + describe('archived version recovery', () => { it('recovers the v3 whole-unit archive through the legacy bootstrap', async () => { const root = await mkdtemp(join(tmpdir(), 'dsh-projcache-fx-')) diff --git a/packages/session/session-projection-cache/tests/fixtures/v7-opaque-session-doc.json b/packages/session/session-projection-cache/tests/fixtures/v7-opaque-session-doc.json new file mode 100644 index 0000000000..5bf96ab142 --- /dev/null +++ b/packages/session/session-projection-cache/tests/fixtures/v7-opaque-session-doc.json @@ -0,0 +1,76 @@ +{ + "version": 7, + "record": { + "identity": { + "formatVersion": 3, + "createdAt": 42, + "isSeeded": false, + "inheritedEventCount": 0 + }, + "rows": { + "opaque-values": { + "ver": 1, + "seq": 0, + "val": { + "__proto__": { + "retained": "state" + }, + "constructor": { + "retained": "state-constructor" + }, + "records": [ + { + "kind": "opaque-record", + "record": { + "category": "sample", + "key": "saved-record", + "entries": [ + { + "kind": "opaque-extension", + "name": "vendor", + "data": { + "__proto__": { + "retained": "extension" + }, + "constructor": { + "retained": "extension-constructor" + }, + "nested": [ + { + "__proto__": { + "retained": "nested" + }, + "value": [ + null, + false, + true, + 0, + 7, + "text" + ] + } + ] + } + } + ], + "metadata": { + "__proto__": { + "retained": "result" + }, + "constructor": { + "retained": "result-constructor" + }, + "metadata": { + "__proto__": { + "retained": "nested-result" + } + } + } + } + } + ] + } + } + } + } +} diff --git a/packages/session/session-telemetry-otel/tests/otel.spec.ts b/packages/session/session-telemetry-otel/tests/otel.spec.ts index 4e15d9058f..754f87bd2d 100644 --- a/packages/session/session-telemetry-otel/tests/otel.spec.ts +++ b/packages/session/session-telemetry-otel/tests/otel.spec.ts @@ -571,9 +571,13 @@ describe('OpenTelemetrySessionBackend route and feedback', () => { const session = ctx.sessions.create(SessionId('live-ratings')) const handle = await ctx.sessionPersistence.create(session.header) try { + session.append('turn/start', { turn: 1 }) + session.append('step/start', { turn: 1, step: 1 }) if (provider !== undefined) session.append('request/header', { header: { config: { provider, model: 'm' } }, reason: 'initial' }) const message = createAssistantMessage({ content: [{ type: 'text', text: 'answer' }], source: { provider: provider ?? 'mock', model: 'm' } }) session.append('assistant/message', { message, stream: [], turn: 1, step: 1 }, { surfaceOp: 'append' }) + session.append('step/end', { turn: 1, step: 1 }) + session.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) const request = { sessionId: session.id, messageId: message.id, rating: 'positive' as const, ifVersion: null } const before = session.seq expect((await ctx.messageFeedback.put({ ...request, note: ' ' })).ok).toBe(false) @@ -639,9 +643,13 @@ describe('OpenTelemetrySessionBackend route and feedback', () => { await ctx.plugin(MessageFeedbackService, { maxNoteBytes: 1024 }) await ctx.plugin(OpenTelemetrySessionBackend, { mode, exporter: { url }, processor: { scheduledDelayMillis: 1 } }) const parent = Session.create(SessionId('cold-parent')) + parent.append('turn/start', { turn: 1 }) + parent.append('step/start', { turn: 1, step: 1 }) parent.append('request/header', { header: { config: { provider: 'mock', model: 'm' } }, reason: 'initial' }) const message = createAssistantMessage({ content: [{ type: 'text', text: 'inherited answer' }], source: { provider: 'mock', model: 'm' } }) parent.append('assistant/message', { message, stream: [], turn: 1, step: 1 }, { surfaceOp: 'append' }) + parent.append('step/end', { turn: 1, step: 1 }) + parent.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) const child = Session.create(SessionId('cold-child'), parent.snapshotEvents(), { ...parent.header, id: SessionId('cold-child'), parentSession: parent.id, isSeeded: true, }, parent.seq) @@ -669,7 +677,8 @@ describe('OpenTelemetrySessionBackend route and feedback', () => { rmSync(root, { recursive: true, force: true }) } expect(eventTypes(captures)).toEqual([ - 'request/header', 'assistant/message', 'session/end-seed', 'feedback/record', 'feedback/message-put', + 'turn/start', 'step/start', 'request/header', 'assistant/message', 'step/end', 'turn/end', + 'session/end-seed', 'feedback/record', 'feedback/message-put', ]) expect(allRecords(captures).some(record => record.scope.endsWith('/ops'))).toBe(false) }) @@ -690,9 +699,13 @@ describe('OpenTelemetrySessionBackend route and feedback', () => { await ctx.plugin(MessageFeedbackService, { maxNoteBytes: 1024 }) await ctx.plugin(OpenTelemetrySessionBackend, { mode, exporter: { url }, processor: { scheduledDelayMillis: 1 } }) const session = Session.create(SessionId('cold-feedback')) + session.append('turn/start', { turn: 1 }) + session.append('step/start', { turn: 1, step: 1 }) if (provider !== undefined) session.append('request/header', { header: { config: { provider, model: 'm' } }, reason: 'initial' }) const message = createAssistantMessage({ content: [{ type: 'text', text: 'answer' }], source: { provider: provider ?? 'mock', model: 'm' } }) session.append('assistant/message', { message, stream: [], turn: 1, step: 1 }, { surfaceOp: 'append' }) + session.append('step/end', { turn: 1, step: 1 }) + session.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) const handle = await ctx.sessionPersistence.create(session.header) try { await handle.append(session.snapshotEvents()) diff --git a/packages/session/session-telemetry/README.i18n.yaml b/packages/session/session-telemetry/README.i18n.yaml index b31416d4ea..b51d905506 100644 --- a/packages/session/session-telemetry/README.i18n.yaml +++ b/packages/session/session-telemetry/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/session/session-telemetry/README.md -README.md: ba503adf55409ada47dc89b68ee37029ab0381d6 -README.zh.md: 5e7237ddac46f4eaab2850186153158e3d36b99a +README.md: c7d76686415ee4874e29ec191d8456c31a3019f4 +README.zh.md: 2e9bc7e6619f30d18660ef2a11ab703b02647aa3 diff --git a/packages/session/session-telemetry/README.md b/packages/session/session-telemetry/README.md index ba503adf55..c7d7668641 100644 --- a/packages/session/session-telemetry/README.md +++ b/packages/session/session-telemetry/README.md @@ -78,7 +78,7 @@ Live capture registers Session events, flush hints, shutdown markers, and agent/ ### The handoff cursor -A module-scope `WeakMap` records the highest sequence handed off, not delivered. Re-adopting the same object resumes after that cursor. Capture normally starts at `firstLiveSeq`; explicit `includeHistory: true` starts an unhanded object at seq 0, including restored or fork history. The backend owns capture authorization. Stored history does not itself authorize capture; the OTel backend waits for new explicit feedback. Receivers deduplicate repeated records by `(session.id, session.format_version, event.seq)`. +A module-scope `WeakMap` records the highest sequence handed off, not delivered. Re-adopting the same object resumes after that cursor. Capture starts at `firstLifecycleSeq`: a new fork includes its child-owned marker and closers, while a restored Session excludes its stored prefix, including prior child turns; explicit `includeHistory: true` starts an unhanded object at seq 0, including restored or fork history. The backend owns capture authorization. Stored history does not itself authorize capture; the OTel backend waits for new explicit feedback. Receivers deduplicate repeated records by `(session.id, session.format_version, event.seq)`. diff --git a/packages/session/session-telemetry/README.zh.md b/packages/session/session-telemetry/README.zh.md index 5e7237ddac..2e9bc7e661 100644 --- a/packages/session/session-telemetry/README.zh.md +++ b/packages/session/session-telemetry/README.zh.md @@ -78,7 +78,7 @@ seam 建立在一个边界之上:harness 的职责止于 `emit()`。完整事 ### handoff 游标 -模块作用域的 `WeakMap` 记录已交接而非已投递的最高序号。重新收养同一对象时从该游标之后继续。捕获通常从 `firstLiveSeq` 开始;显式 `includeHistory: true` 从未交接对象的 seq 0 开始,包含恢复或 fork 历史。后端负责捕获授权。存储的历史本身不授权捕获;OTel 后端等待新的显式反馈。接收方按 `(session.id, session.format_version, event.seq)` 对重复记录去重。 +模块级 `WeakMap` 记录已经移交的最高序号,而不是已送达的最高序号。再次接管同一对象时从该游标之后继续。采集从 `firstLifecycleSeq` 开始:新 fork 包含子会话自有的标记与 fork 结束事件;恢复的 Session 排除已存储前缀,包括先前的子会话轮次。显式 `includeHistory: true` 会让尚未移交的对象从 seq 0 开始,包括恢复或 fork 历史。Backend 负责采集授权;已有存储历史本身不构成授权,OTel backend 等待新的显式反馈。接收方通过 `(session.id, session.format_version, event.seq)` 对重复记录去重。 diff --git a/packages/session/session-telemetry/src/coordinator.ts b/packages/session/session-telemetry/src/coordinator.ts index 14c9916c64..7f3b5d6052 100644 --- a/packages/session/session-telemetry/src/coordinator.ts +++ b/packages/session/session-telemetry/src/coordinator.ts @@ -33,7 +33,7 @@ export type SessionTelemetryCapture = 'live' | 'on-demand' export interface SessionTelemetryCaptureOptions { /** Follow live events, or wait for explicit capture; defaults to live. */ capture?: SessionTelemetryCapture - /** Include stored history before this lifecycle; defaults to false. */ + /** Include inherited fork history and stored history from earlier lifecycles; defaults to false. */ includeHistory?: boolean } @@ -149,8 +149,9 @@ export class SessionTelemetryCoordinator { * @param throughSeq - optional last sequence included in this capture. */ captureSession(session: Session, throughSeq?: SessionSeqType): void { + const start = session.firstLifecycleSeq const cursor = handoffCursor.get(session) - ?? (this.options.includeHistory === true || session.firstLiveSeq === 0 ? -1 : SessionSeq(session.firstLiveSeq - 1)) + ?? (this.options.includeHistory === true || start === 0 ? -1 : SessionSeq(start - 1)) // Containment is PER EVENT: one rejected record is withheld fail-closed // while the rest of the historical replay proceeds. // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred. @@ -164,9 +165,9 @@ export class SessionTelemetryCoordinator { /** * Adopt a session and replay after its handoff cursor, then follow live events. - * New objects include inherited and restored history only with includeHistory; - * otherwise replay starts at the constructor boundary. Re-adopting the same - * object resumes after its cursor. + * New fork objects include child-owned seed markers and closers. Restored + * objects start after the stored prefix, including restored forks. includeHistory starts either object at seq 0; + * re-adopting the same object resumes after its cursor. * @param session - the live session to adopt; a second adoption is a no-op. */ private adopt(session: Session): void { @@ -267,7 +268,7 @@ function shutdownRecord(session: Session): SessionTelemetryRecord { function severityOf(event: SessionEvent): SessionTelemetrySeverity { switch (event.type) { case 'tool/result': - return event.data.message.content[0].isError === true ? 'error' : 'info' + return event.data.message.isError === true ? 'error' : 'info' case 'turn/end': return event.data.reason.kind === 'error' ? 'error' : 'info' default: diff --git a/packages/session/session-telemetry/src/index.ts b/packages/session/session-telemetry/src/index.ts index 8840423617..392df907f7 100644 --- a/packages/session/session-telemetry/src/index.ts +++ b/packages/session/session-telemetry/src/index.ts @@ -47,7 +47,7 @@ declare module '@deepseek-ai/cordis' { /** * Severity of a telemetry record, pre-mapped at capture so a receiver can * alert with zero configuration: `error` for events whose own outcome flag - * says so (the tool-result block's `isError`, `turn/end` error reasons) and for + * says so (the tool message's `isError`, `turn/end` error reasons) and for * `agent-error` operational records. Captured events otherwise default to * `info`; `warn` remains available to `session-telemetry/record` policies and * backends. diff --git a/packages/session/session-telemetry/tests/telemetry.spec.ts b/packages/session/session-telemetry/tests/telemetry.spec.ts index ac9ffdcfc0..2d8c02ed64 100644 --- a/packages/session/session-telemetry/tests/telemetry.spec.ts +++ b/packages/session/session-telemetry/tests/telemetry.spec.ts @@ -1,4 +1,4 @@ -import { createAssistantMessage, createToolResultMessage, createUserMessage } from '@deepseek-ai/dsh-llm' +import { createAssistantMessage, createToolResultMessage, createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' /** * Coordinator semantics against a bare fake backend — the RFC's named unit * tier for the seam: adoption (fresh, seeded, re-adoption via the handoff @@ -299,8 +299,8 @@ describe('SessionTelemetryCoordinator on-demand capture', () => { }) const parent = liveSession(ctx, 'history-parent') appendTurn(parent) - const child = ctx.sessions.create(SessionId('history-child'), { seed: [...parent.snapshotEvents()] }) - const boundary = child.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) + const child = ctx.sessions.fork(parent, undefined, SessionId('history-child')) + const boundary = child.snapshotEvents().at(-1)! child.append('turn/start', { turn: 2 }) expect(backend.records).toEqual([]) coordinator.captureSession(child, boundary.seq) @@ -387,6 +387,96 @@ describe('SessionTelemetryCoordinator on-demand capture', () => { }) describe('SessionTelemetryCoordinator adoption', () => { + it.each([ + { capture: 'live', includeHistory: false }, + { capture: 'on-demand', includeHistory: false }, + { capture: 'live', includeHistory: true }, + { capture: 'on-demand', includeHistory: true }, + ] as const)('restores a seeded Session with $capture capture and includeHistory=$includeHistory', async (options) => { + const ctx = new Context() + try { + await ctx.plugin(SessionStore) + const parent = liveSession(ctx, 'cold-parent') + appendTurn(parent) + parent.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) + const child = ctx.sessions.fork(parent, undefined, SessionId('cold-child')) + child.append('turn/start', { turn: 2 }) + child.append('turn/end', { turn: 2, reason: { kind: 'completed' } }) + const resumedId = SessionId('restored-child') + const resumed = Session.fromRestore(resumedId, child.snapshotEvents(), { ...child.header, id: resumedId }, + child.inheritedEventCount, 'shared-frozen') + const backend = new FakeBackend() + let coordinator!: SessionTelemetryCoordinator + await ctx.plugin({ + name: 'seeded-resume-telemetry', inject: ['sessions'], + apply: (inner: Context) => { coordinator = new SessionTelemetryCoordinator(inner, backend, options) }, + }) + ctx.sessions.enter(resumed) + ctx.sessions.announce(resumed) + const expected = resumed.snapshotEvents().slice(options.includeHistory ? 0 : resumed.firstLiveSeq) + const captured = () => backend.ledger().filter(record => record.attributes['session.id'] === resumedId) + expect(captured().map(record => record.attributes['event.seq'])) + .toEqual(options.capture === 'live' ? expected.map(event => event.seq) : []) + coordinator.captureSession(resumed) + coordinator.captureSession(resumed) + expect(captured().map(record => record.attributes['event.seq'])).toEqual(expected.map(event => event.seq)) + expect(expected.at(-1)?.type).toBe('session/end-seed') + } finally { + await ctx.fiber.dispose() + } + }) + + it.each(['live', 'on-demand'] as const)('captures the child-owned fork marker and closers in %s mode', async (capture) => { + const { ctx, backend, coordinator, fiber } = await setup(new FakeBackend(), capture) + try { + const parent = liveSession(ctx, 'fork-parent') + appendTurn(parent) + parent.append('step/start', { turn: 1, step: 1 }) + parent.append('assistant/message', { + turn: 1, step: 1, stream: [], + message: createAssistantMessage({ + content: [{ type: 'tool-call', id: ToolCallId('fork-call'), name: 'bash', arguments: '{}' }], + source: { provider: 'mock', model: 'mock' }, + }), + }, { surfaceOp: 'append' }) + parent.append('tool/call', { + turn: 1, step: 1, callId: ToolCallId('fork-call'), name: 'bash', arguments: '{}', + }) + const child = ctx.sessions.fork(parent, undefined, SessionId('fork-child')) + const ownEvents = child.snapshotEvents().slice(child.inheritedEventCount) + expect(ownEvents.map(event => event.type)).toEqual([ + 'session/end-seed', 'tool/result', 'step/end', 'turn/end', + ]) + expect(child.firstLiveSeq).toBe(child.inheritedEventCount + ownEvents.length) + const captured = () => backend.ledger().filter(record => record.attributes['session.id'] === child.id) + expect(captured().map(record => record.attributes['event.seq'])) + .toEqual(capture === 'live' ? ownEvents.map(event => event.seq) : []) + + coordinator.captureSession(child) + coordinator.captureSession(child) + expect(captured().map(record => record.attributes['event.seq'])).toEqual(ownEvents.map(event => event.seq)) + expect(captured().map(record => record.body)).toEqual(ownEvents.map(event => event.data)) + + await fiber.dispose() + const second = new FakeBackend() + let reloaded!: SessionTelemetryCoordinator + await ctx.plugin({ + name: 'fork-telemetry-reloaded', + inject: ['sessions'], + apply: (inner: Context) => { + reloaded = new SessionTelemetryCoordinator(inner, second, { capture }) + }, + }) + reloaded.captureSession(child) + expect(second.ledger()).toEqual([]) + const next = child.append('turn/start', { turn: 2 }) + reloaded.captureSession(child) + expect(second.ledger().map(record => record.attributes['event.seq'])).toEqual([next.seq]) + } finally { + await ctx.fiber.dispose() + } + }) + it('replays a new fork object from its constructor boundary without its inherited prefix', async () => { const backend = new FakeBackend() const ctx = new Context() diff --git a/packages/session/session-title-llm/src/index.ts b/packages/session/session-title-llm/src/index.ts index d0092ec956..837160a50d 100644 --- a/packages/session/session-title-llm/src/index.ts +++ b/packages/session/session-title-llm/src/index.ts @@ -7,6 +7,13 @@ import type { Context } from '@deepseek-ai/cordis' import z from '@deepseek-ai/schemastery' import { createUserMessage, BlockAssembler } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'dsh-session-title-llm': { kind: 'dsh-session-title-llm' } & ContextFormed + } +} + import type { FinishReason, GenerateOptions, Message } from '@deepseek-ai/dsh-llm' import { deadline, MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { deepFreeze } from '@deepseek-ai/dsh-util-values' @@ -247,7 +254,7 @@ export async function generateSessionTitleWithLlm( const route = resolveRoute(config, request) const messages: Message[] = [createUserMessage({ content: [{ type: 'text', text: framedInput }], - source: { kind: 'plugin', plugin: 'dsh-session-title-llm' }, + source: { kind: 'dsh-session-title-llm' }, })] const system = systemPrompt(config) using callDeadline = deadline(request.signal, config.timeoutMs, SESSION_TITLE_TIMEOUT_CODE) diff --git a/packages/session/session-title/tests/invariant.spec.ts b/packages/session/session-title/tests/invariant.spec.ts index 5903c63250..246bd8c67f 100644 --- a/packages/session/session-title/tests/invariant.spec.ts +++ b/packages/session/session-title/tests/invariant.spec.ts @@ -6,6 +6,13 @@ import * as SessionTitleInvariantCompanion from '@deepseek-ai/dsh-session-title/ import InvariantRegistry, { InvariantError } from '@deepseek-ai/dsh-invariants' import SessionStore, { SessionId, SessionSeq } from '@deepseek-ai/dsh-session' import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' + +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} async function setup(): Promise { const ctx = new Context() @@ -64,7 +71,7 @@ describe('session-title source invariant', () => { })).toThrow(/invalid message seq/) const pluginMessage = session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'plugin context' }], - source: { kind: 'plugin', plugin: 'test' }, + source: { kind: 'test' }, }), { surfaceOp: 'append' }) expect(() => session.append('session/title', { title: 'plugin source', messageSeqs: [pluginMessage.seq], source: { kind: 'fallback' }, diff --git a/packages/session/session-title/tests/session-title.spec.ts b/packages/session/session-title/tests/session-title.spec.ts index 69edbb84ff..1349c52d4b 100644 --- a/packages/session/session-title/tests/session-title.spec.ts +++ b/packages/session/session-title/tests/session-title.spec.ts @@ -1,4 +1,5 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import SessionStore, { Session, SessionId, SessionSeq } from '@deepseek-ai/dsh-session' @@ -11,6 +12,12 @@ import SessionTitleService, { truncateTitleUtf8, } from '@deepseek-ai/dsh-session-title' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'seed': { kind: 'seed' } & ContextFormed + } +} + const CONFIG = { fallbackMaxWords: 5, fallbackMaxBytes: 40, @@ -113,7 +120,7 @@ describe('SessionTitleService', () => { }) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'plugin text' }], - source: { kind: 'plugin', plugin: 'seed' }, + source: { kind: 'seed' }, }), { surfaceOp: 'append' }) session.append('user/message', createUserMessage({ content: [{ type: 'reasoning', text: 'not visible text' }], diff --git a/packages/session/session-turn-outline/tests/projection.spec.ts b/packages/session/session-turn-outline/tests/projection.spec.ts index 959e5587b4..c01acf8aa5 100644 --- a/packages/session/session-turn-outline/tests/projection.spec.ts +++ b/packages/session/session-turn-outline/tests/projection.spec.ts @@ -12,6 +12,7 @@ import { describe, expect, expectTypeOf, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { createAssistantMessage, createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' @@ -19,6 +20,12 @@ import * as SessionTurnOutlinePlugin from '@deepseek-ai/dsh-session-turn-outline import { turnOutlineProjectionDefinition } from '@deepseek-ai/dsh-session-turn-outline/src/projection.ts' import type { TurnOutlineEntry, TurnOutlineState } from '@deepseek-ai/dsh-session-turn-outline/types' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test-injector': { kind: 'test-injector' } & ContextFormed + } +} + async function harness(withOutlinePlugin: boolean): Promise<{ ctx: Context; session: Session }> { const ctx = new Context() await ctx.plugin(SessionStore) @@ -136,7 +143,7 @@ describe('turn outline projection unit', () => { session.append('turn/start', { turn: 1 }) session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'injected context' }], - source: { kind: 'plugin', plugin: 'test-injector', form: 'relay' }, + source: { kind: 'test-injector', form: 'relay' }, }), { surfaceOp: 'append' }) expect(outlineOf(ctx, session)).toEqual([ { turn: 1, seq: 1, prompt: '', response: '' }, diff --git a/packages/shell/tool-bash/tests/integration.spec.ts b/packages/shell/tool-bash/tests/integration.spec.ts index 013eaacf58..0aa4ad7925 100644 --- a/packages/shell/tool-bash/tests/integration.spec.ts +++ b/packages/shell/tool-bash/tests/integration.spec.ts @@ -76,7 +76,7 @@ function findEvent( function resultText(event: SessionEvent): string { if (event.type !== 'tool/result') return '' - return event.data.message.content[0].content + return event.data.message.content .filter(block => block.type === 'text') .map(block => block.text) .join('') @@ -136,14 +136,12 @@ describe('bash tool through the agent loop', () => { expect(toolCall.data.name).toBe('bash') const toolResult = findEvent(log, 'tool/result') - expect(toolResult.data.message.content[0].isError).toBe(false) + expect(toolResult.data.message.isError).toBe(false) expect(resultText(toolResult)).toBe('integration-ok\n') // The second model call saw the tool result in its derived history. const lastRequest = adapter.requests.at(-1) - const toolResultBlocks = (lastRequest?.messages ?? []) - .flatMap(message => message.content) - .filter(block => block.type === 'tool-result') + const toolResultBlocks = (lastRequest?.messages ?? []).filter(message => message.role === 'tool') expect(toolResultBlocks).toHaveLength(1) const finalMessage = findEvent(log, 'assistant/message', 'last') @@ -164,7 +162,7 @@ describe('bash tool through the agent loop', () => { await waitForIdle(ctx, agent) const toolResult = findEvent(events(agent), 'tool/result') - expect(toolResult.data.message.content[0].isError).toBe(false) + expect(toolResult.data.message.isError).toBe(false) expect(resultText(toolResult)).toContain('[exit code: 9]') }) @@ -197,11 +195,11 @@ describe('bash tool through the agent loop', () => { await waitForIdle(ctx, agent) const firstResult = findEvent(events(agent), 'tool/result') - expect(firstResult.data.message.content[0].isError).toBe(false) + expect(firstResult.data.message.isError).toBe(false) expect(resultText(firstResult)).toBe('started background job bash-1') // The turn closed with the task still running, so the notice cannot exist yet. const isNotice = (e: SessionEvent): e is SessionEvent<'user/message'> => - e.type === 'user/message' && e.data.source.kind === 'plugin' + e.type === 'user/message' && e.data.source.kind !== 'user' expect(events(agent).some(isNotice)).toBe(false) // Releasing the command now settles it against a provably idle owner. No @@ -224,12 +222,11 @@ describe('bash tool through the agent loop', () => { expect(noticeText).toContain('background job bash-1 (bash: ') expect(noticeText).toContain('finished [status: completed, exit code: 0]') expect(notice.data.source).toMatchObject({ - kind: 'plugin', - plugin: 'tool-jobs', + kind: 'tool-jobs', form: 'notice', }) const readResult = findEvent(events(agent), 'tool/result', 'last') - expect(readResult.data.message.content[0].isError).toBe(false) + expect(readResult.data.message.isError).toBe(false) expect(resultText(readResult)).toContain('bg-ok') expect(resultText(readResult)).toContain('[status: completed, exit code: 0]') }) diff --git a/packages/skill/tool-skill/tests/tool-skill.spec.ts b/packages/skill/tool-skill/tests/tool-skill.spec.ts index 603166de04..7d9fb0d2f0 100644 --- a/packages/skill/tool-skill/tests/tool-skill.spec.ts +++ b/packages/skill/tool-skill/tests/tool-skill.spec.ts @@ -4,6 +4,7 @@ import { join } from 'node:path' import { tmpdir } from 'node:os' import { Context } from '@deepseek-ai/cordis' import { createUserMessage, ToolCallId, type Message } from '@deepseek-ai/dsh-llm' +import type { ContextFormed, MessageSource } from '@deepseek-ai/dsh-llm' import { createScope, type Scope } from '@deepseek-ai/dsh-scope' import { SESSION_FORMAT_VERSION, Session, SessionId, type SessionEvent, type UserMessage, @@ -16,6 +17,20 @@ import * as SkillFileSystem from '@deepseek-ai/dsh-skill-filesystem' import * as toolSkill from '@deepseek-ai/dsh-tool-skill' import { unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'dsh-tool-skill': { kind: 'dsh-tool-skill' } & ContextFormed + 'later-contribution': { kind: 'later-contribution' } & ContextFormed + } +} + +type CheckpointSource = Extract + +/** Build a typed checkpoint source for a skill projection fixture. */ +function checkpointSource(compactionId: string): CheckpointSource { + return { kind: 'compact-checkpoint', compactionId: compactionId as CheckpointSource['compactionId'] } +} + const testToolSignal = new AbortController().signal /** Every temp dir created by this file, removed after each test. */ @@ -261,7 +276,7 @@ describe('dsh-tool-skill', () => { ...decision.messages, createUserMessage({ content: [{ type: 'text', text: 'later contribution' }], - source: { kind: 'plugin', plugin: 'later-contribution' }, + source: { kind: 'later-contribution' }, }), ], } @@ -274,7 +289,7 @@ describe('dsh-tool-skill', () => { id: expect.any(String) as unknown, role: 'user', content: [{ type: 'text', text: 'later contribution' }], - source: { kind: 'plugin', plugin: 'later-contribution' }, + source: { kind: 'later-contribution' }, }, { id: expect.any(String) as unknown, @@ -534,7 +549,7 @@ describe('dsh-tool-skill', () => { }), { surfaceOp: 'append' }) session.append('user/message', createUserMessage({ content: catalogContent(['- `resumed-skill`: Resumed skill']), - source: { kind: 'plugin', plugin: 'dsh-tool-skill' }, + source: { kind: 'dsh-tool-skill' }, }), { surfaceOp: 'append' }) await fireStep(ctx, agent, 1, 1) @@ -628,7 +643,7 @@ describe('dsh-tool-skill', () => { if (initial === undefined) throw new Error('expected initial catalog') session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'compacted history' }], - source: { kind: 'plugin', plugin: 'compact' }, + source: checkpointSource('skill-compaction'), }), { surfaceOp: { op: 'replace', startSeq: initial.seq, endSeq: initial.seq }, sourceEventSeqs: [initial.seq], diff --git a/packages/spill/spill-policy/tests/spill-policy.spec.ts b/packages/spill/spill-policy/tests/spill-policy.spec.ts index db559bc338..d2b4a12ca4 100644 --- a/packages/spill/spill-policy/tests/spill-policy.spec.ts +++ b/packages/spill/spill-policy/tests/spill-policy.spec.ts @@ -13,6 +13,7 @@ import { Context } from '@deepseek-ai/cordis' import Loader from '@deepseek-ai/cordis-plugin-loader' import { createUserMessage, ToolCallId } from '@deepseek-ai/dsh-llm' import type { ContentBlock } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime, { defineContentToolFixture } from '@deepseek-ai/dsh-tools' @@ -28,6 +29,12 @@ import Sandbox from '@deepseek-ai/dsh-sandbox-local' import SandboxPolicy from '@deepseek-ai/dsh-sandbox-policy' import SessionProjections from '@deepseek-ai/dsh-session-projection' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'test': { kind: 'test' } & ContextFormed + } +} + async function mountRuntime(ctx: Context, config: NodeRuntimeConfig = {}): Promise { onTestFinished(async () => { await ctx.fiber.dispose() }) if (!ctx.get('sessions')) await ctx.plugin(SessionStore) @@ -552,7 +559,7 @@ describe('composition', () => { const { ctx } = await setup({ maxInlineBytes: 200 }) const context = createUserMessage({ content: [{ type: 'text' as const, text: 'note' }], - source: { kind: 'plugin' as const, plugin: 'test' }, + source: { kind: 'test' as const }, }) ctx.on('tools/post-execute', async (_e, _r, _next) => ({ kind: 'accept', additionalContexts: [context] })) diff --git a/packages/subagent/subagent-acp/src/run.ts b/packages/subagent/subagent-acp/src/run.ts index 3164c5d634..59413da0f2 100644 --- a/packages/subagent/subagent-acp/src/run.ts +++ b/packages/subagent/subagent-acp/src/run.ts @@ -476,7 +476,7 @@ export async function startAcpRun(request: SubagentStartRequest, spec: AcpRunSpe request.signal.addEventListener('abort', onAbort, { once: true }) // Read at every return so a partial answer survives a later cancel/error. - const collectOutput = (): ContentBlock[] => fold.collect() ?? [] + const collectOutput = (): readonly ContentBlock[] => fold.collect() ?? [] // Establish the remote session before publishing a handle. Any failure owns // the still-private process and therefore reaps it before rejecting. diff --git a/packages/subagent/subagent-acp/tests/fixtures/loader/mock-delegating-llm.ts b/packages/subagent/subagent-acp/tests/fixtures/loader/mock-delegating-llm.ts index f318424153..ca1f556656 100644 --- a/packages/subagent/subagent-acp/tests/fixtures/loader/mock-delegating-llm.ts +++ b/packages/subagent/subagent-acp/tests/fixtures/loader/mock-delegating-llm.ts @@ -10,12 +10,13 @@ import { ToolCallId, LlmAdapter } from '@deepseek-ai/dsh-llm' */ class MockDelegatingAdapter extends LlmAdapter { async * stream(options: GenerateOptions): AsyncIterable { - const toolResultText = options.messages.at(-1)?.content - .filter(block => block.type === 'tool-result') - .flatMap(block => block.content) - .filter(block => block.type === 'text') - .map(block => block.text) - .join('') ?? '' + const last = options.messages.at(-1) + const toolResultText = last?.role === 'tool' + ? last.content + .filter(block => block.type === 'text') + .map(block => block.text) + .join('') + : '' if (toolResultText.length === 0) { const args = JSON.stringify({ description: 'cwd probe', prompt: 'report your workspace' }) diff --git a/packages/subagent/subagent-acp/tests/loader-composition.e2e.ts b/packages/subagent/subagent-acp/tests/loader-composition.e2e.ts index 2d93909fab..791cb36b06 100644 --- a/packages/subagent/subagent-acp/tests/loader-composition.e2e.ts +++ b/packages/subagent/subagent-acp/tests/loader-composition.e2e.ts @@ -37,7 +37,7 @@ async function jsonlFiles(dir: string): Promise { function toolResultText(events: SessionEvent[]): string { const results = events.filter(event => event.type === 'tool/result') expect(results).toHaveLength(1) - return results[0]!.data.message.content[0].content + return results[0]!.data.message.content .filter(block => block.type === 'text') .map(block => block.text) .join('') diff --git a/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts b/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts index 6db46da475..25a25a5e88 100644 --- a/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts +++ b/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts @@ -59,7 +59,7 @@ async function setup(mockEnv: SetupEnv = {}, permission: 'allow' | 'reject' = 'r return ctx } -function text(blocks: { type: string; text?: string }[]): string { +function text(blocks: readonly { type: string; text?: string }[]): string { return blocks.filter(b => b.type === 'text').map(b => b.text).join('') } diff --git a/packages/subagent/subagent-dsh-sdk/src/run.ts b/packages/subagent/subagent-dsh-sdk/src/run.ts index 565b9860bd..165952b5a5 100644 --- a/packages/subagent/subagent-dsh-sdk/src/run.ts +++ b/packages/subagent/subagent-dsh-sdk/src/run.ts @@ -303,7 +303,7 @@ export async function startSdkRun(request: SubagentStartRequest, spec: SdkRunSpe if (notification.method !== 'session.event' || notification.params.sessionId !== childSessionId) return fold.push(notification.params.event as SessionEvent) } - const collectOutput = (): ContentBlock[] => fold.collect() ?? [] + const collectOutput = (): readonly ContentBlock[] => fold.collect() ?? [] const teardown = async (): Promise => { try { await harness.close() diff --git a/packages/subagent/subagent-dsh-sdk/tests/fixtures/loader/mock-delegating-llm.ts b/packages/subagent/subagent-dsh-sdk/tests/fixtures/loader/mock-delegating-llm.ts index f07a50379c..1a102296ef 100644 --- a/packages/subagent/subagent-dsh-sdk/tests/fixtures/loader/mock-delegating-llm.ts +++ b/packages/subagent/subagent-dsh-sdk/tests/fixtures/loader/mock-delegating-llm.ts @@ -25,12 +25,13 @@ class MockDelegatingAdapter extends LlmAdapter { } async * stream(options: GenerateOptions): AsyncIterable { - const toolResultText = options.messages.at(-1)?.content - .filter(block => block.type === 'tool-result') - .flatMap(block => block.content) - .filter(block => block.type === 'text') - .map(block => block.text) - .join('') ?? '' + const last = options.messages.at(-1) + const toolResultText = last?.role === 'tool' + ? last.content + .filter(block => block.type === 'text') + .map(block => block.text) + .join('') + : '' if (toolResultText.length === 0) { const selectedRoute = process.env.DSH_TEST_CHILD_DEFAULT_ROUTE === '1' diff --git a/packages/subagent/subagent-dsh-sdk/tests/loader-composition.e2e.ts b/packages/subagent/subagent-dsh-sdk/tests/loader-composition.e2e.ts index 5ea51ec585..ae9b8e8609 100644 --- a/packages/subagent/subagent-dsh-sdk/tests/loader-composition.e2e.ts +++ b/packages/subagent/subagent-dsh-sdk/tests/loader-composition.e2e.ts @@ -41,7 +41,7 @@ async function sessionEvents(log: string): Promise { function toolResultText(events: SessionEvent[]): string { const results = events.filter(event => event.type === 'tool/result') expect(results).toHaveLength(1) - return results[0]!.data.message.content[0].content + return results[0]!.data.message.content .filter(block => block.type === 'text') .map(block => block.text) .join('') @@ -114,7 +114,7 @@ describe('SDK subagent routing and diagnostics through the production profile', // process's launch directory. const results = events.filter(event => event.type === 'tool/result') expect(results).toHaveLength(1) - const resultText = results[0]!.data.message.content[0].content + const resultText = results[0]!.data.message.content .filter(block => block.type === 'text') .map(block => block.text) .join('') diff --git a/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts b/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts index ba26c0c69c..99a9d93b27 100644 --- a/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts +++ b/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts @@ -102,7 +102,7 @@ async function setup(fakeEnv: Record = {}, config: Partial b.type === 'text').map(b => b.text).join('') } diff --git a/packages/subagent/subagent-fork-in-process/tests/multi-subagent.spec.ts b/packages/subagent/subagent-fork-in-process/tests/multi-subagent.spec.ts index 35c8af4df3..26b54630d0 100644 --- a/packages/subagent/subagent-fork-in-process/tests/multi-subagent.spec.ts +++ b/packages/subagent/subagent-fork-in-process/tests/multi-subagent.spec.ts @@ -45,7 +45,7 @@ async function setup(script: Script) { return { ctx, parent } } -function text(blocks: { type: string; text?: string }[]): string { +function text(blocks: readonly { type: string; text?: string }[]): string { return blocks.filter(b => b.type === 'text').map(b => b.text).join('') } diff --git a/packages/subagent/subagent-fork-in-process/tests/subagent-fork-in-process.spec.ts b/packages/subagent/subagent-fork-in-process/tests/subagent-fork-in-process.spec.ts index 6f7080cd31..2f34a7d359 100644 --- a/packages/subagent/subagent-fork-in-process/tests/subagent-fork-in-process.spec.ts +++ b/packages/subagent/subagent-fork-in-process/tests/subagent-fork-in-process.spec.ts @@ -52,7 +52,7 @@ async function setup(script: Script) { return { ctx, parent } } -function text(blocks: { type: string; text?: string }[]): string { +function text(blocks: readonly { type: string; text?: string }[]): string { return blocks.filter(b => b.type === 'text').map(b => b.text).join('') } diff --git a/packages/subagent/subagent-in-process-driver/src/index.ts b/packages/subagent/subagent-in-process-driver/src/index.ts index 91348b2da9..dbaac326b1 100644 --- a/packages/subagent/subagent-in-process-driver/src/index.ts +++ b/packages/subagent/subagent-in-process-driver/src/index.ts @@ -223,7 +223,7 @@ function readResult( // `error` through `toStopReason(undefined)`, which never overstates success. const lastEnd = foldConsumedWork(own).end // The seam's canonical selection rule; a partial answer survives cancel and truncation. - const output: ContentBlock[] = finalAssistantOutput(own) ?? [] + const output: readonly ContentBlock[] = finalAssistantOutput(own) ?? [] const recorded = toStopReason(lastEnd?.data.reason) // Disposal can tear the owner down before the loop records its ordinary // `aborted` end, yielding `disposed` instead. diff --git a/packages/subagent/subagent-in-process-driver/tests/inheritance.spec.ts b/packages/subagent/subagent-in-process-driver/tests/inheritance.spec.ts index 81a34bc3c3..ac20f24f99 100644 --- a/packages/subagent/subagent-in-process-driver/tests/inheritance.spec.ts +++ b/packages/subagent/subagent-in-process-driver/tests/inheritance.spec.ts @@ -73,7 +73,6 @@ function toolResultTexts(agent: Agent): string[] { return agent.session.snapshotEvents() .filter((event): event is SessionEvent<'tool/result'> => event.type === 'tool/result') .map(event => event.data.message.content - .flatMap(block => block.content) .filter((block): block is Extract => block.type === 'text') .map(block => block.text) .join('')) @@ -173,8 +172,7 @@ describe('in-process policy inheritance', () => { ) const runtimeContext = child.session.snapshotEvents().find( (event): event is SessionEvent<'user/message'> => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt', + && event.data.source.kind === 'runtime-context', ) if (request === undefined || systemNode === undefined || runtimeContext === undefined) { throw new Error('child request lacks its system node or runtime policy context') diff --git a/packages/subagent/subagent-in-process-driver/tests/structured.spec.ts b/packages/subagent/subagent-in-process-driver/tests/structured.spec.ts index 1ec0b16852..9d06368496 100644 --- a/packages/subagent/subagent-in-process-driver/tests/structured.spec.ts +++ b/packages/subagent/subagent-in-process-driver/tests/structured.spec.ts @@ -199,7 +199,7 @@ describe('in-process structured output', () => { const child = ctx.agents.get(run.id) const sideEffectResult = child?.session.snapshotEvents().find(event => event.type === 'tool/result' && event.data.message.source.callId === 'c2') - expect(sideEffectResult?.type === 'tool/result' && sideEffectResult.data.message.content[0].isError).toBe(true) + expect(sideEffectResult?.type === 'tool/result' && sideEffectResult.data.message.isError).toBe(true) await run.dispose() }) @@ -243,7 +243,7 @@ describe('in-process structured output', () => { const child = ctx.agents.get(run.id)! const results = child.session.snapshotEvents().filter(e => e.type === 'tool/result') expect(results.length).toBe(2) - expect(results[0]!.data.message.content[0].isError).toBe(true) + expect(results[0]!.data.message.isError).toBe(true) await run.dispose() }) @@ -259,7 +259,7 @@ describe('in-process structured output', () => { // Exactly one model request and one caller-supplied user message: no nudge turn exists. expect(adapter.requests.length).toBe(1) const child = ctx.agents.get(run.id)! - expect(child.session.snapshotEvents().filter(e => e.type === 'user/message' && e.data.source.kind !== 'plugin').length).toBe(1) + expect(child.session.snapshotEvents().filter(e => e.type === 'user/message' && e.data.source.kind !== 'runtime-context').length).toBe(1) await run.dispose() }) @@ -325,7 +325,7 @@ describe('in-process structured output', () => { // ...the logged tool result is the blocked isError with the feedback... const child = ctx.agents.get(run.id)! const results = child.session.snapshotEvents().filter(e => e.type === 'tool/result') - expect(results[0]!.data.message.content[0].isError).toBe(true) + expect(results[0]!.data.message.isError).toBe(true) expect(JSON.stringify(results[0]!.data.message.content)).toContain('capture rejected by hook') // ...and the turn CONTINUED past the blocked call (no captured veto): // the model got to react to the failure with a second step. @@ -371,7 +371,7 @@ describe('in-process structured output', () => { const child = ctx.agents.get(run.id) const captureResult = child?.session.snapshotEvents().find(event => event.type === 'tool/result' && event.data.message.source.callId === 'c1') - expect(captureResult?.type === 'tool/result' && captureResult.data.message.content[0].isError).toBe(true) + expect(captureResult?.type === 'tool/result' && captureResult.data.message.isError).toBe(true) await run.dispose() }) @@ -443,7 +443,7 @@ describe('in-process structured output', () => { const child = ctx.agents.get(run.id)! const outer = child.session.snapshotEvents().find(event => event.type === 'tool/result' && event.data.message.source.callId === ToolCallId('c1')) - expect(outer?.type === 'tool/result' && outer.data.message.content[0].isError).toBe(true) + expect(outer?.type === 'tool/result' && outer.data.message.isError).toBe(true) await run.dispose() }) diff --git a/packages/subagent/subagent-in-process-driver/tests/subagent-in-process-driver.spec.ts b/packages/subagent/subagent-in-process-driver/tests/subagent-in-process-driver.spec.ts index d11fa73b05..3c50c9debf 100644 --- a/packages/subagent/subagent-in-process-driver/tests/subagent-in-process-driver.spec.ts +++ b/packages/subagent/subagent-in-process-driver/tests/subagent-in-process-driver.spec.ts @@ -1,4 +1,5 @@ import { ToolCallId, createUserMessage } from '@deepseek-ai/dsh-llm' +import type { ContextFormed } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { type Agent, type AgentOptions } from '@deepseek-ai/dsh-agent' @@ -14,6 +15,12 @@ import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' import { maxTokensResponse, MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' import { startInProcessRun } from '../src/index.ts' +declare module '@deepseek-ai/dsh-llm' { + interface MessageSourceMap { + 'late-metadata': { kind: 'late-metadata' } & ContextFormed + } +} + type Script = ConstructorParameters[0] async function mountInvariants(ctx: Context): Promise { @@ -155,7 +162,7 @@ describe('startInProcessRun', () => { injected = true session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'late metadata' }], - source: { kind: 'plugin', plugin: 'late-metadata' }, + source: { kind: 'late-metadata' }, }), { surfaceOp: 'append' }) }) diff --git a/packages/subagent/subagent-spawn-in-process/tests/subagent-spawn-in-process.spec.ts b/packages/subagent/subagent-spawn-in-process/tests/subagent-spawn-in-process.spec.ts index 5df47ab30e..e199b7c9aa 100644 --- a/packages/subagent/subagent-spawn-in-process/tests/subagent-spawn-in-process.spec.ts +++ b/packages/subagent/subagent-spawn-in-process/tests/subagent-spawn-in-process.spec.ts @@ -46,7 +46,7 @@ async function setup(script: Script) { return { ctx, parent, adapter } } -function text(blocks: { type: string; text?: string }[]): string { +function text(blocks: readonly { type: string; text?: string }[]): string { return blocks.filter(b => b.type === 'text').map(b => b.text).join('') } diff --git a/packages/subagent/subagent/README.i18n.yaml b/packages/subagent/subagent/README.i18n.yaml index 8194c11b6b..f2d1e1d365 100644 --- a/packages/subagent/subagent/README.i18n.yaml +++ b/packages/subagent/subagent/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/subagent/README.md -README.md: d6fa74d2b31eafe867e0a3c22dbaae4cef008a6a -README.zh.md: 6159ae10c56f7c9bf0274279f092fbc552af009c +README.md: 7d62e423189906c49d9479bd7a6dbd14b7303afd +README.zh.md: af62ad97bc4821222d46ed73509c823851953e1d diff --git a/packages/subagent/subagent/README.md b/packages/subagent/subagent/README.md index d6fa74d2b3..7d62e42318 100644 --- a/packages/subagent/subagent/README.md +++ b/packages/subagent/subagent/README.md @@ -60,7 +60,7 @@ One-shot children run once and settle with a single result, plus an optional str ### Messaging, interrupting, and discovering -Every exact live Agent can use `sendMessage()` with a direct continuable child; a resident continuable child can also use it with its direct parent. A working target receives the Agent message through Steer at its nearest step; an idle target starts a turn, and only a direct child can be cold-resumed. The parent can also interrupt a running descendant or list its children at any time. A browser continuation prompt independently selects Queue or Steer and may carry image parts: the Host admits and persists each image batch through the attachment store before the child inbox accepts the message, and refuses delivery when the child's declared model does not accept image input. Discovery covers both shapes: the service lists direct children and the full descendant tree — mode, live activity, latest closed-turn completion, and lineage — reading live session state and optional persistence, without loading any child. +Every exact live Agent can use `sendMessage()` with a direct continuable child; a resident continuable child can also use it with its direct parent. A working target receives the Agent message through Steer at its nearest step; an idle target starts a turn, and only a direct child can be cold-resumed. The parent can also interrupt a running descendant or list its children at any time. A browser continuation prompt independently selects Queue or Steer and may carry image parts: the Host admits and persists each image batch through the attachment store before the child inbox accepts the message, and refuses delivery when the child's declared model does not accept image input. Direct-child discovery reads the parent-owned `subagentCatalog` projection. `listChildren(parentSessionId, signal?)` owns a live-preferred Session observation and returns the catalog asynchronously without reading child logs. It forwards cancellation and releases the observation after materialization. Materialization preserves parent event order in O(D) time for D facts. Complete descendant discovery retains the Session corpus and child identity projection; neither path loads or resumes a child Agent. ### Failure and recovery @@ -95,9 +95,10 @@ This section explains how the service is built and where the observable behavior | [`src/inbox.ts`](src/inbox.ts) | Activation-local Queue and Steer admission plus the synchronous closing cutoff | | [`src/types.ts`](src/types.ts) | Public request, result, and provider contracts | | [`src/descriptor.ts`](src/descriptor.ts) | Versioned `subagent/descriptor` session-event vocabulary | +| [`src/catalog.ts`](src/catalog.ts) | Parent-owned `subagent/catalog` event and chunked host projection | | [`src/child-agent.ts`](src/child-agent.ts) | Child composition, delegated policy, depth helpers | -| [`src/list-children.ts`](src/list-children.ts) | Discovery over the live session store and optional persistence | -| [`src/control.ts`](src/control.ts) | Browser control assembly: catalog activity sampling, browser-zone validation, failure codes | +| [`src/list-children.ts`](src/list-children.ts) | Direct parent-catalog reads and complete descendant-corpus reads | +| [`src/control.ts`](src/control.ts) | Browser control request validation and stable failure codes | | [`src/control-types.ts`](src/control-types.ts) | Client-safe catalog row, control requests, receipts, and failures | ### One-shot flow diff --git a/packages/subagent/subagent/README.zh.md b/packages/subagent/subagent/README.zh.md index 6159ae10c5..af62ad97bc 100644 --- a/packages/subagent/subagent/README.zh.md +++ b/packages/subagent/subagent/README.zh.md @@ -60,7 +60,7 @@ kind: "package-reference" ### 消息、中断与发现 -每个确切在线 Agent 都可以对直接可继续 child 使用 `sendMessage()`;驻留的可继续 child 还可以对自己的直接 parent 使用它。正在工作的目标通过 Steer 在最近 step 接收 Agent 消息;空闲目标启动轮次,且只有直接 child 可以冷恢复。parent 也可以随时中断正在运行的后代或列举自己的子级。浏览器发出的继续执行提示词会独立选择 Queue 或 Steer,并且可以携带图片部分:Host 先通过附件存储完成整批图片的准入与持久化,子级 inbox 才接受这条消息;当子级声明的模型不接受图片输入时拒绝投递。发现覆盖两种形态:服务列举直接子级与完整后代树——模式、在线活动状态、最近已结束轮次的完成状态与谱系——直接读取在线会话状态与可选持久化,不加载任何子 agent。 +每个确切在线 Agent 都可以对直接可继续 child 使用 `sendMessage()`;驻留的可继续 child 还可以对自己的直接 parent 使用它。正在工作的目标通过 Steer 在最近 step 接收 Agent 消息;空闲目标启动轮次,且只有直接 child 可以冷恢复。parent 也可以随时中断正在运行的后代或列举自己的子级。浏览器发出的继续执行 prompt 会独立选择 Queue 或 Steer,并且可以携带图片部分:Host 先通过附件存储完成整批图片的准入与持久化,子级 inbox 才接受这条消息;当子级声明的模型不接受图片输入时拒绝投递。 直接子级发现读取 parent 自有的 `subagentCatalog` projection。`listChildren(parentSessionId, signal?)` 持有一次优先实时来源的 Session 观察,异步返回目录,不读取子级日志。它转发取消信号,并在物化后释放观察。物化以 O(D) 时间保留 D 条事实的父日志事件顺序。完整后代发现保留 Session 语料库与子级身份 projection;两条路径都不加载或恢复子级 Agent。 ### 失败与恢复 @@ -95,9 +95,10 @@ kind: "package-reference" | [`src/inbox.ts`](src/inbox.ts) | Activation 局部的 Queue 和 Steer 准入,以及同步 closing cutoff | | [`src/types.ts`](src/types.ts) | 公开的请求、结果与提供方约定 | | [`src/descriptor.ts`](src/descriptor.ts) | 版本化的 `subagent/descriptor` 会话事件词汇 | +| [`src/catalog.ts`](src/catalog.ts) | parent 自有的 `subagent/catalog` 事件与分块 host projection | | [`src/child-agent.ts`](src/child-agent.ts) | 子级组装、委派策略、深度辅助函数 | -| [`src/list-children.ts`](src/list-children.ts) | 基于在线会话存储与可选持久化的发现 | -| [`src/control.ts`](src/control.ts) | 浏览器控制面组装:目录活性采样、浏览器时区校验、失败分码 | +| [`src/list-children.ts`](src/list-children.ts) | 直接 parent 目录读取与完整后代语料读取 | +| [`src/control.ts`](src/control.ts) | 浏览器控制请求校验与稳定失败分码 | | [`src/control-types.ts`](src/control-types.ts) | client-safe 的目录行、控制面请求、回执与失败 | ### 一次性流程 diff --git a/packages/subagent/subagent/src/assistant-output.ts b/packages/subagent/subagent/src/assistant-output.ts index 2961082deb..1094a107a5 100644 --- a/packages/subagent/subagent/src/assistant-output.ts +++ b/packages/subagent/subagent/src/assistant-output.ts @@ -20,7 +20,7 @@ import type { SessionEvent } from '@deepseek-ai/dsh-session' * text into the same streamed fallback. */ export class AssistantOutputFold { - private message: ContentBlock[] | undefined + private message: readonly ContentBlock[] | undefined private partial: string[] = [] /** @@ -52,7 +52,7 @@ export class AssistantOutputFold { * @returns the last non-empty assistant message, else the accumulated * streamed text, or `undefined` when the child produced neither. */ - collect(): ContentBlock[] | undefined { + collect(): readonly ContentBlock[] | undefined { if (this.message !== undefined) return this.message const text = this.partial.join('') return text.length > 0 ? [{ type: 'text', text }] : undefined @@ -64,7 +64,7 @@ export class AssistantOutputFold { * @param events - the child-owned events (after any seed or epoch boundary). * @returns the selected output, or `undefined` when the child produced none. */ -export function finalAssistantOutput(events: readonly SessionEvent[]): ContentBlock[] | undefined { +export function finalAssistantOutput(events: readonly SessionEvent[]): readonly ContentBlock[] | undefined { // TODO: this folds the complete suffix once per run/epoch settlement. If a // long continuable epoch ever profiles hot here, scan backward with early // exit for the last non-empty message and fold text deltas only on the diff --git a/packages/subagent/subagent/src/control-types.ts b/packages/subagent/subagent/src/control-types.ts index 0325da892f..10a8cfc426 100644 --- a/packages/subagent/subagent/src/control-types.ts +++ b/packages/subagent/subagent/src/control-types.ts @@ -1,7 +1,6 @@ /** - * Client-safe subagent catalog and control vocabulary: the durable direct-child - * row both the listing and the browser catalog answer with, plus the - * browser-facing control surface's prompt, receipts, and failures. + * Client-safe complete-descendant rows and browser continuation requests, + * receipts, and failures. * * @module @deepseek-ai/dsh-subagent/control-types */ @@ -20,46 +19,41 @@ import type { SessionId } from '@deepseek-ai/dsh-session/types' */ export type SubagentPromptRequestId = Branded<'session-request-id'> -/** - * One durable direct-child row, ordered by header `createdAt` with ties broken - * on id. Only a candidate whose durable header has `origin: 'subagent'` is - * interpreted. A served `subagent` projection value produces a `child`; a - * settled candidate whose fold served no identity produces a `diagnostic`; a - * running candidate without one is omitted — its descriptor may not be - * appended yet (the creation window). Diagnostics relay the projection fold's - * outcome or a failed read, never a per-child event scan, and never expose - * model-hidden descriptor content. - */ -export type SubagentListEntry = - | { - readonly kind: 'child' +/** Shared child fields for complete-descendant listing. */ +export type SubagentCatalogRow = + & { /** The durable child session id, stable across Activations. */ readonly id: SessionId /** - * Whether the child is live at the moment its reader sampled it: the - * durable listing reads the Session store (`running` means the logical - * record is resident, `inactive` that it exists only in persistence), - * while the browser catalog re-samples the child's Agent driver. Neither - * encodes a durable outcome, and a continuable child may still reject - * delivery as an ownership conflict. + * Whether complete-descendant listing observed a resident Session. This + * does not encode a durable outcome or guarantee continuation delivery. */ readonly activity: 'running' | 'inactive' - /** Whether a direct descendant has durable `origin: 'subagent'`. */ - readonly hasChildren: boolean } & ( | { /** A terminal one-shot child. */ readonly mode: 'one-shot' - /** Optional durable creation label from the child's descriptor. */ + /** Optional durable creation label from the owning catalog or child descriptor. */ readonly label?: string } | { /** A resumable conversation. */ readonly mode: 'continuable' - /** Durable creation label from the child's descriptor. */ + /** Durable creation label from the owning catalog or child descriptor. */ readonly label: string } ) + +/** + * One complete-descendant row. Enumeration may also return diagnostics for + * child identity observations from the complete Session corpus. + */ +export type SubagentListEntry = + | SubagentCatalogRow & { + readonly kind: 'child' + /** Whether complete-corpus enumeration observed a direct child. */ + readonly hasChildren: boolean + } | { readonly kind: 'diagnostic' /** The candidate's session id. */ @@ -77,12 +71,6 @@ export type SubagentListEntry = readonly reason: 'corrupt' | 'unsupported' | 'unavailable' } -/** Complete direct-child catalog plus the delivery-time parent availability hint. */ -export interface SubagentCatalog { - readonly entries: readonly SubagentListEntry[] - readonly parentAvailable: boolean -} - /** Durable parent/child address that selects subagent transport in the client. */ export type SubagentAddress = & { @@ -125,8 +113,8 @@ export interface SubagentInterruptReceipt { } /** - * Failure details the control surface answers with. Catalog reads, prompts, - * and interrupts share this vocabulary with the Client Remote result. + * Failure details the control surface answers with. Prompts and interrupts + * share these failures with the Client Remote result. */ declare module '@deepseek-ai/dsh-typert-protocol' { interface RemoteErrorDetailsMap { @@ -142,7 +130,5 @@ declare module '@deepseek-ai/dsh-typert-protocol' { 'subagent/attachment-invalid': { readonly reason: string } /** The child exists but its inbox cannot admit the message now. */ 'subagent/delivery-unavailable': { readonly childSessionId: SessionId } - /** The deployment mounts no session-projection registry. */ - 'subagent/projections-unavailable': {} } } diff --git a/packages/subagent/subagent/src/control.ts b/packages/subagent/subagent/src/control.ts index 54e4057513..670566ef0a 100644 --- a/packages/subagent/subagent/src/control.ts +++ b/packages/subagent/subagent/src/control.ts @@ -1,22 +1,18 @@ /** - * Browser-facing subagent control assembly: the catalog view sampled against - * the live Agent registry, one browser zone's validation, and the stable - * failure codes the Remote surface answers with. + * Browser-facing subagent prompt and interrupt request validation plus the + * stable prompt failure codes returned by the Remote surface. * * @module @deepseek-ai/dsh-subagent */ -import type { Context } from '@deepseek-ai/cordis' import { AttachmentError } from '@deepseek-ai/dsh-attachment' import type { SessionId } from '@deepseek-ai/dsh-session' import { RemoteError } from '@deepseek-ai/dsh-typert-protocol' import { z } from 'zod' -import type { SubagentCatalog, SubagentListEntry } from './control-types.ts' import { SubagentError } from './error.ts' const SESSION_ID_SCHEMA = z.string().min(1) const CONTROL_ID_SCHEMAS = { - 'subagent.list': z.object({ parentSessionId: SESSION_ID_SCHEMA }), 'subagent.prompt': z.object({ parentSessionId: SESSION_ID_SCHEMA, childSessionId: SESSION_ID_SCHEMA, @@ -47,53 +43,6 @@ export function validateControlRequest( } } -/** - * Project one durable listing onto the catalog view, replacing each row's - * store-derived activity with the live Agent driver's status and reporting - * whether the exact parent Agent is live. Without an Agent registry no driver - * runs at all, so every row is inactive and the parent is unavailable. - * @param ctx - Host context that may carry the Agent registry. - * @param parentSessionId - the listed parent. - * @param entries - the durable direct-child listing. - * @returns the catalog view answered to one browser. - */ -export function catalogView( - ctx: Context, - parentSessionId: SessionId, - entries: readonly SubagentListEntry[], -): SubagentCatalog { - const agents = ctx.get('agents') - return { - entries: entries.map((entry): SubagentListEntry => entry.kind === 'child' - ? { ...entry, activity: agents?.get(entry.id)?.status === 'running' ? 'running' : 'inactive' } - : entry), - parentAvailable: agents?.get(parentSessionId) !== undefined, - } -} - -/** - * Refuse one catalog read while preserving cancellation and a missing - * projections registry as distinct failures. - * @param error - the thrown value. - * @param signal - the caller's cancellation. - * @returns Never — the refusal is thrown. - * @throws {RemoteError} always. - */ -export function rejectCatalogRead(error: unknown, signal: AbortSignal): never { - if (isCancellation(error, signal)) { - throw new RemoteError('gateway/cancelled', 'subagent catalog read was cancelled', {}, { cause: error }) - } - if (error instanceof SubagentError && error.code === 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE') { - throw new RemoteError( - 'subagent/projections-unavailable', - 'subagent catalog is unavailable: this deployment does not mount the sessionProjections registry (load @deepseek-ai/dsh-session-projection)', - {}, - { cause: error }, - ) - } - throw new RemoteError('gateway/internal', 'subagent catalog read failed', {}, { cause: error }) -} - /** * Refuse one continuation prompt without exposing provider detail: admission * failures the caller can act on keep their own code, everything else is diff --git a/packages/subagent/subagent/src/index.ts b/packages/subagent/subagent/src/index.ts index 5d2941be6a..0262c37476 100644 --- a/packages/subagent/subagent/src/index.ts +++ b/packages/subagent/subagent/src/index.ts @@ -17,9 +17,9 @@ * is resident. Continuable children never become a {@link SubagentRun}: the * continuation manager holds their `AgentHandle` directly and orders every turn * through the child's own inbox, so providers contribute only the detached - * creation spec and see no handle, turn, or teardown. Child and descendant - * discovery read the live session store and optional session persistence - * directly and do not require that continuation runtime. + * creation spec and see no handle, turn, or teardown. Direct-child + * discovery uses the parent catalog; descendant discovery uses the Session + * corpus. Neither read requires the continuation runtime. * * Same-process providers are trusted typed collaborators. Requests, provider * descriptors, results, and lifecycle payloads are borrowed immutable values; @@ -42,10 +42,9 @@ import type { SessionId } from '@deepseek-ai/dsh-session' import { canonicalClientTimeZone } from '@deepseek-ai/dsh-util-time' import { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol' import { - catalogView, rejectCatalogRead, rejectPrompt, validateControlRequest, + rejectPrompt, validateControlRequest, } from './control.ts' import type { - SubagentCatalog, SubagentInterruptReceipt, SubagentPromptReceipt, SubagentPromptRequest, @@ -73,10 +72,11 @@ import type { ActivationObserver, LifecycleEmitter } from './lifecycle.ts' import SubagentContinuationManager from './continuation.ts' import type { SubagentDelivery } from './inbox.ts' import { listChildren as listSubagentChildren, listDescendants as listSubagentDescendants } from './list-children.ts' -import type { SubagentDescendantListEntry, SubagentListEntry } from './list-children.ts' +import type { SubagentDescendantListEntry } from './list-children.ts' import { snapshotSubagentDescriptor } from './descriptor.ts' import { subagentIdentityProjectionDefinition, subagentTimingProjectionDefinition } from './projection.ts' import { establishCatalogChild, subagentCatalogProjectionDefinition } from './catalog.ts' +import type { SubagentCatalogEntry } from './projection-types.ts' import { deliverSubagentPrompt } from './internal.ts' export type {} from './catalog.ts' @@ -112,6 +112,7 @@ export type { SubagentDescriptorData, SubagentDescriptorInput, } from './descriptor.ts' +export type { SubagentCatalogEntry } from './projection-types.ts' export { SubagentError } from './error.ts' export { settleRun } from './run-settlement.ts' export { assertSubagentMaxDepth, delegationDepthOf } from './depth.ts' @@ -234,9 +235,10 @@ export class SubagentRuntime extends TypertRemoteService { }, 'subagents.continuationBinding()') }) ctx.inject(['sessionProjections'], (projectionCtx) => { - projectionCtx.sessionProjections.register(subagentCatalogProjectionDefinition) - projectionCtx.sessionProjections.register(subagentTimingProjectionDefinition) - projectionCtx.sessionProjections.register(subagentIdentityProjectionDefinition) + const projections = projectionCtx.sessionProjections + projections.register(subagentCatalogProjectionDefinition) + projections.register(subagentTimingProjectionDefinition) + projections.register(subagentIdentityProjectionDefinition) }) } @@ -364,23 +366,15 @@ export class SubagentRuntime extends TypertRemoteService { } /** - * Enumerate the parent's direct session-backed subagents without loading or - * resuming an Agent. The Session query service supplies one live-preferred - * corpus and shared point observations; the projection cache supplies - * immutable descriptor hits without opening cold logs. The registered - * `subagent` projection remains the sole mode/label classifier. - * - * Every query receives `signal`, and the listing rechecks cancellation - * around each await. Read rejections that settle - * after an abort become a stable `SubagentError` with code `CANCELLED`. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - caller-owned cancellation forwarded to Session queries - * and observed around every read await. - * @returns children and per-child diagnostics ordered by `createdAt`, then id. - * @throws {@link SubagentError} when the projection registry or the session - * store is not mounted, or the caller cancels the listing. + * Read the parent's durable direct-child catalog without loading or resuming an Agent. + * The service owns and releases the live-preferred Session observation. + * @param parentSessionId - parent whose direct children are requested. + * @param signal - cancellation forwarded to the Session query. + * @returns catalog children in parent event order. + * @throws {@link SubagentError} when query or catalog projection is unavailable. + * @throws SessionQueryError when the parent cannot be read or the query is cancelled. */ - listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise { + listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise { return listSubagentChildren(this.ctx, parentSessionId, signal) } @@ -390,42 +384,19 @@ export class SubagentRuntime extends TypertRemoteService { * Agent. Ordinary sessions and one-shot children remain traversal nodes so * continuable descendants below them are discovered; each returned entry * adds its durable `parentId` and root-relative `depth`. Identity resolution, - * diagnostics, optional persistence, and cancellation follow the same - * projection-backed contract as {@link listChildren}. + * diagnostics, optional persistence, and cancellation use the registered + * child identity projection and complete Session corpus. * @param rootSessionId - session whose complete descendant tree is listed. * @param signal - caller-owned cancellation forwarded to persistence reads * and observed around every read await. * @returns children and per-candidate diagnostics with tree position, in * stable pre-order. - * @throws {@link SubagentError} under the same conditions as {@link listChildren}. + * @throws {@link SubagentError} when listing dependencies are unavailable or the caller cancels. */ listDescendants(rootSessionId: SessionId, signal?: AbortSignal): Promise { return listSubagentDescendants(this.ctx, rootSessionId, signal) } - /** - * Remote face of {@link listChildren} for one browser: the durable listing - * plus live Agent activity and the delivery-time parent availability hint. - * Parent availability is a hint; {@link prompt} performs the authoritative - * check. Named apart from the provider-name {@link list}, which owns the - * member. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - carrier cancellation forwarded to Session queries. - * @returns the catalog view for that parent. - * @throws {RemoteError} `gateway/bad-request` for an empty parent id, - * `gateway/cancelled` for an aborted read, `subagent/projections-unavailable` when - * the deployment has no projection registry, otherwise `gateway/internal`. - */ - @Remote('list') - async remoteExportList(parentSessionId: SessionId, signal: AbortSignal): Promise { - validateControlRequest('subagent.list', { parentSessionId }) - try { - return catalogView(this.ctx, parentSessionId, await this.listChildren(parentSessionId, signal)) - } catch (error: unknown) { - return rejectCatalogRead(error, signal) - } - } - /** * Deliver one browser-authored message to a continuable child through the * exact live direct parent, retaining the caller-minted request identity and diff --git a/packages/subagent/subagent/src/lifecycle.ts b/packages/subagent/subagent/src/lifecycle.ts index adeba106f6..d0ccf55b30 100644 --- a/packages/subagent/subagent/src/lifecycle.ts +++ b/packages/subagent/subagent/src/lifecycle.ts @@ -33,7 +33,7 @@ export interface ActivationTerminal { /** Why this epoch's last ordinary turn ended, or `error` when teardown failed. */ readonly stopReason: SubagentResult['stopReason'] /** The epoch's final assistant content, absent when it produced none or failed. */ - readonly output?: ContentBlock[] + readonly output?: readonly ContentBlock[] } /** @@ -253,9 +253,10 @@ function epochStopReason(events: readonly SessionEvent[]): SubagentResult['stopR case undefined: case 'completed': return droppedUnrun ? 'aborted' : 'completed' - /* v8 ignore next 3 -- `TurnEndReason` is merge-extensible, so this arm needs a - * backend that adds a variant; treating an unnameable reason as success would - * report failed work as completed. */ + /* v8 ignore next 4 -- `forked` appears only in constructor seed history, while + * this function reads an epoch-owned suffix. `TurnEndReason` is merge-extensible, + * so a backend-added variant cannot be listed; treating an unnameable reason as + * success would report failed work as completed. */ default: return 'error' } diff --git a/packages/subagent/subagent/src/list-children.ts b/packages/subagent/subagent/src/list-children.ts index 1d2c58ba6d..9de66e771c 100644 --- a/packages/subagent/subagent/src/list-children.ts +++ b/packages/subagent/subagent/src/list-children.ts @@ -1,31 +1,23 @@ /** - * Read-only enumeration of durable subagent children and descendant trees - * through the Session query service. Candidates come from one live-preferred - * corpus; each child's mode/label is the registered `subagent` projection - * unit's value, resolved - * down a three-rung ladder: the registry's watermark cache for a live child, - * an unseeded durable projection-cache row, and one shared Session observation - * otherwise. A seeded header deliberately lacks its exact inherited cut, so - * it takes the body-bearing observation path before classifying an identity. - * The projection fold is the single classification - * authority — this module parses no descriptor - * itself. Absent persistence, enumeration is live-only: a cold child is - * unreachable for resume anyway, so its absence is capability absence, not an - * error. The module owns no catalog state and does not consult Activation, - * Agent-registry, continuation-manager, or provider state. + * Direct-child discovery from a parent-owned `subagent/catalog` projection, + * plus complete descendant-tree enumeration from the Session corpus. A direct + * listing owns one parent observation and reads no child log. Descendant + * enumeration retains the complete corpus and the child identity projection + * because ordinary Sessions and one-shot children remain traversal nodes. * * @module @deepseek-ai/dsh-subagent */ import type { Context } from '@deepseek-ai/cordis' -import { SessionLogOffset } from '@deepseek-ai/dsh-session' -import type { Session, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' +import { type Session, SessionLogOffset } from '@deepseek-ai/dsh-session' +import type { SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import type { SessionProjectionRegistry } from '@deepseek-ai/dsh-session-projection' import type { SessionProjectionCache } from '@deepseek-ai/dsh-session-projection-cache' import type { SessionObservation, SessionQueryEngine } from '@deepseek-ai/dsh-session-query' import type { SubagentListEntry } from './control-types.ts' import { SubagentError } from './error.ts' import type { SubagentIdentityProjection } from './projection-types.ts' +import type { SubagentCatalogEntry } from './projection-types.ts' export type { SubagentListEntry } from './control-types.ts' @@ -65,47 +57,49 @@ interface PositionedCandidate { } /** - * Enumerate one parent's origin-classified direct children from the - * live-preferred merge of `ctx.sessions` and optional session persistence, - * serving each identity from the `subagent` projection unit: the registry's - * watermark snapshot for a live child; for a cold one, a durable - * projection-cache read for an unseeded lifecycle, else one bounded-concurrency - * shared Session observation carrying the exact inherited cut. - * @see SubagentRuntime.listChildren for the public cancellation and failure contract. - * @param ctx - context carrying the session store, the projection registry, - * optional persistence, and the optional projection cache. - * @param parentSessionId - parent session whose direct children are listed. - * @param signal - caller-owned cancellation observed around every persistence read. - * @returns children and per-child diagnostics ordered by `createdAt`, then id. - * @throws {@link SubagentError} when the projection registry or the session - * store is not mounted, or the caller cancels the listing. + * Read one parent's durable catalog through a live-preferred Session observation. + * @param ctx - context carrying the Session query service. + * @param parentSessionId - parent whose direct children are requested. + * @param signal - cancellation forwarded to the Session observation. + * @returns direct-child rows in parent catalog event order. + * @throws {@link SubagentError} when query or catalog projection is unavailable. */ export async function listChildren( ctx: Context, parentSessionId: SessionId, signal?: AbortSignal, -): Promise { - const listing = await prepareListing(ctx, signal) - const candidates = [...listing.corpus.values()] - .filter(record => record.header.parentSession === parentSessionId - && record.header.origin === 'subagent') - .sort(compareCorpusRecords) - const rows = await resolveCandidateRows(candidates, listing, signal) - return rows.filter((row): row is SubagentListEntry => row !== undefined) +): Promise { + const query = ctx.get('sessionQuery') + if (query === undefined) { + throw new SubagentError( + 'listing subagents requires the sessionQuery service (load @deepseek-ai/dsh-session-query)', + 'SUBAGENT_CONTROL_QUERY_UNAVAILABLE', + ) + } + using parent = await query.observeSession(parentSessionId, { + ...signal === undefined ? {} : { signal }, + }) + const entries = parent.projections?.values.subagentCatalog + if (entries === undefined) { + throw new SubagentError( + 'listing subagents requires the registered subagentCatalog projection', + 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE', + ) + } + return entries } /** * Enumerate every session-backed subagent below one root in stable pre-order. * Ordinary sessions and one-shot children remain traversal nodes, so a * continuable child below either is still discovered. Classification uses the - * same projection-backed runtime as {@link listChildren}; no Agent is loaded or - * resumed. + * registered child identity projection; no Agent is loaded or resumed. * @see SubagentRuntime.listDescendants for the public cancellation and failure contract. * @param ctx - context carrying the session store, projection registry, and optional persistence/cache. * @param rootSessionId - session whose complete descendant tree is listed. * @param signal - caller-owned cancellation observed around every persistence read. * @returns interpreted subagents with durable direct-parent and root-relative depth. - * @throws {@link SubagentError} under the same conditions as {@link listChildren}. + * @throws {@link SubagentError} when listing dependencies are unavailable or the caller cancels. */ export async function listDescendants( ctx: Context, diff --git a/packages/subagent/subagent/src/out-of-process.ts b/packages/subagent/subagent/src/out-of-process.ts index 4dc158a240..adfc566afb 100644 --- a/packages/subagent/subagent/src/out-of-process.ts +++ b/packages/subagent/subagent/src/out-of-process.ts @@ -166,7 +166,7 @@ export interface RunResultSettlement { /** The turn attempt (typically racing local cancellation); returns the terminal result. */ attempt: () => Promise /** Snapshot the provider exposes when cancellation or failure wins settlement. */ - collectOutput: () => ContentBlock[] + collectOutput: () => readonly ContentBlock[] /** Snapshot safe provider-authored detail when a failure wins settlement. */ collectDiagnostic?: (() => string | undefined) | undefined /** Whether local cancellation settled before the attempt's outcome is observed. */ diff --git a/packages/subagent/subagent/src/run-settlement.ts b/packages/subagent/subagent/src/run-settlement.ts index 02f61a7baf..90eb9eec43 100644 --- a/packages/subagent/subagent/src/run-settlement.ts +++ b/packages/subagent/subagent/src/run-settlement.ts @@ -11,7 +11,7 @@ import type { JobOutcome } from '@deepseek-ai/dsh-jobs' import type { SubagentResult, SubagentRun } from './types.ts' /** Flatten a child's final output blocks to the task's final text. */ -function finalText(blocks: ContentBlock[]): string { +function finalText(blocks: readonly ContentBlock[]): string { return blocks .filter((block): block is Extract => block.type === 'text') .map(block => block.text) diff --git a/packages/subagent/subagent/src/types.ts b/packages/subagent/subagent/src/types.ts index 1b9ce56c3f..48ac0df1e1 100644 --- a/packages/subagent/subagent/src/types.ts +++ b/packages/subagent/subagent/src/types.ts @@ -113,7 +113,7 @@ export interface SubagentRunEndInfo { * {@link SubagentResult.output}; absent on infrastructure rejection or when * the child produced none. */ - readonly lastAssistantMessage?: ContentBlock[] + readonly lastAssistantMessage?: readonly ContentBlock[] } /** @@ -275,7 +275,7 @@ export interface SubagentResult { * are skipped. Without a non-empty message, the output is its accumulated * assistant text stream, or `[]` when the child produced neither. */ - readonly output: ContentBlock[] + readonly output: readonly ContentBlock[] /** * The structured result after a requested `outputSchema` was successfully * satisfied. Requesting a schema does not guarantee presence: a provider can diff --git a/packages/subagent/subagent/tests/assistant-output.spec.ts b/packages/subagent/subagent/tests/assistant-output.spec.ts index a21694052d..07585a8853 100644 --- a/packages/subagent/subagent/tests/assistant-output.spec.ts +++ b/packages/subagent/subagent/tests/assistant-output.spec.ts @@ -26,15 +26,13 @@ function toolResult(text: string): SessionEvent { type: 'tool/result', data: { message: { - content: [{ - type: 'tool-result', - toolCallId: 'call-1', - content: [{ type: 'text', text }], - isError: false, - }], + role: 'tool', + toolCallId: 'call-1', + content: [{ type: 'text', text }], + isError: false, }, }, - } as SessionEvent + } as unknown as SessionEvent } describe('finalAssistantOutput', () => { diff --git a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts index b4458c3d2e..fcb98097c0 100644 --- a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts +++ b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts @@ -184,8 +184,7 @@ describe('continuable policy inheritance', () => { expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() const runtimeContext = loaded.events.find( (event): event is SessionEvent<'user/message'> => event.type === 'user/message' - && event.data.source.kind === 'plugin' - && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt', + && event.data.source.kind === 'runtime-context', ) const contextText = runtimeContext?.data.content .flatMap(block => block.type === 'text' ? [block.text] : []) diff --git a/packages/subagent/subagent/tests/continuation.spec.ts b/packages/subagent/subagent/tests/continuation.spec.ts index 7f37523cd7..2f8fe9f57e 100644 --- a/packages/subagent/subagent/tests/continuation.spec.ts +++ b/packages/subagent/subagent/tests/continuation.spec.ts @@ -144,7 +144,7 @@ function hasAssistantText(events: readonly SessionEvent[], text: string): boolea /** Caller-supplied user message texts in log order (runtime-context snapshots excluded). */ function userTexts(events: readonly SessionEvent[]): string[] { - return events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' + return events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'runtime-context' ? event.data.content.flatMap(block => block.type === 'text' && !block.text.startsWith('Your parent agent id is ') ? [block.text] @@ -2421,7 +2421,7 @@ describe('continuable review regressions', () => { }) it.each([ - { label: 'plugin', source: { kind: 'plugin' as const, plugin: 'tool-jobs' } }, + { label: 'plugin', source: { kind: 'tool-jobs' as const } }, { label: 'non-plugin', source: { kind: 'team-message', teamId: 't-1' } as never }, ])('keeps an idle child resident while its Inbox holds $label injected context', async ({ source }) => { const release = Promise.withResolvers() @@ -2455,7 +2455,7 @@ describe('continuable review regressions', () => { // a driver, so residency must survive until that turn claims the message. const steered = createUserMessage({ content: message('Cordis Host handler failed'), - source: { kind: 'plugin', plugin: 'cordis-host-runner' }, + source: { kind: 'cordis-host-runner' }, }) child.steer(steered) ctx.subagents.interrupt(started.childId, { kind: 'user', parentSessionId: parent.id }) diff --git a/packages/subagent/subagent/tests/control.spec.ts b/packages/subagent/subagent/tests/control.spec.ts index 0c6b6e27f7..b2e5385c98 100644 --- a/packages/subagent/subagent/tests/control.spec.ts +++ b/packages/subagent/subagent/tests/control.spec.ts @@ -1,7 +1,5 @@ -// The browser-facing control surface: catalog assembly against the live Agent -// registry, prompt admission, and the stable failure codes each answers with. -// The durable listing, continuation, and interrupt primitives they wrap have -// their own specs, so each case scripts them. +// The browser-facing prompt and interrupt controls and their stable failure +// codes. Session Controller owns catalog observation and transport. import { describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' @@ -10,15 +8,13 @@ import type { MessageId } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import SubagentRuntime, { SubagentError, - type SubagentListEntry, type SubagentPromptRequestId, } from '@deepseek-ai/dsh-subagent' import { deliverSubagentPrompt, type HostPromptDeliverer } from '@deepseek-ai/dsh-subagent/internal' const PARENT = SessionId('parent') const CHILD = SessionId('child') -const OTHER = SessionId('other') -const BROKEN = SessionId('broken') +const PARENT_CREATED_AT = 1 const REQUEST_ID = 'req-1' as SubagentPromptRequestId const signal = new AbortController().signal /** Durable-reference base for the fake store; per-test ids and media types override. */ @@ -29,7 +25,14 @@ async function bench(live?: Record) { const ctx = new Context() await ctx.plugin(SubagentRuntime) if (live !== undefined) { - ctx.provide('agents', { get: (id: SessionId) => live[id] } as never) + ctx.provide('agents', { + get: (id: SessionId) => { + const agent = live[id] + return agent === undefined + ? undefined + : { ...agent, session: { header: { createdAt: PARENT_CREATED_AT } } } + }, + } as never) } return { ctx, subagents: ctx.subagents } } @@ -39,10 +42,6 @@ function promptDelivery(subagents: SubagentRuntime) { return vi.spyOn(subagents as unknown as HostPromptDeliverer, deliverSubagentPrompt) } -function childRow(id: SessionId, activity: 'running' | 'inactive'): SubagentListEntry { - return { kind: 'child', id, mode: 'continuable', label: 'worker', activity, hasChildren: false } -} - function promptRequest(clientTimeZone?: string, delivery: 'queue' | 'steer' = 'queue') { return { requestId: REQUEST_ID, @@ -72,81 +71,6 @@ function emptyIdFailure(method: string, field: string) { } } -describe('subagent catalog Remote', () => { - it('rejects an empty parent id before listing', async () => { - const { subagents } = await bench() - const listChildren = vi.spyOn(subagents, 'listChildren') - - await expect(subagents.remoteExportList(SessionId(''), signal)) - .rejects.toMatchObject(emptyIdFailure('subagent.list', 'parentSessionId')) - expect(listChildren).not.toHaveBeenCalled() - }) - - it('samples row activity from the live Agent driver and reports parent availability', async () => { - const { subagents } = await bench({ [PARENT]: { status: 'idle' }, [CHILD]: { status: 'running' } }) - vi.spyOn(subagents, 'listChildren').mockResolvedValue([ - // The durable listing reports store presence; the browser row reports the driver. - childRow(CHILD, 'inactive'), - childRow(OTHER, 'running'), - { kind: 'diagnostic', id: BROKEN, reason: 'corrupt' }, - ]) - - await expect(subagents.remoteExportList(PARENT, signal)).resolves.toEqual({ - entries: [ - childRow(CHILD, 'running'), - childRow(OTHER, 'inactive'), - { kind: 'diagnostic', id: BROKEN, reason: 'corrupt' }, - ], - parentAvailable: true, - }) - }) - - it('reports every row inactive and the parent unavailable without an Agent registry', async () => { - const { subagents } = await bench() - vi.spyOn(subagents, 'listChildren').mockResolvedValue([childRow(CHILD, 'running')]) - - await expect(subagents.remoteExportList(PARENT, signal)).resolves.toEqual({ - entries: [childRow(CHILD, 'inactive')], - parentAvailable: false, - }) - }) - - it('reports an unknown parent as unavailable while the registry serves other sessions', async () => { - const { subagents } = await bench({ [CHILD]: { status: 'running' } }) - vi.spyOn(subagents, 'listChildren').mockResolvedValue([]) - - await expect(subagents.remoteExportList(PARENT, signal)) - .resolves.toEqual({ entries: [], parentAvailable: false }) - }) - - it('separates cancellation, the missing projections capability, and an unexplained read failure', async () => { - const { subagents } = await bench() - const listChildren = vi.spyOn(subagents, 'listChildren') - - const aborted = new AbortController() - aborted.abort() - listChildren.mockRejectedValue(new Error('read stopped')) - await expect(subagents.remoteExportList(PARENT, aborted.signal)) - .rejects.toMatchObject({ code: 'gateway/cancelled' }) - - listChildren.mockRejectedValue(new SubagentError('cancelled', 'CANCELLED')) - await expect(subagents.remoteExportList(PARENT, signal)) - .rejects.toMatchObject({ code: 'gateway/cancelled' }) - - listChildren.mockRejectedValue( - new SubagentError('no registry', 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE'), - ) - await expect(subagents.remoteExportList(PARENT, signal)).rejects.toMatchObject({ - code: 'subagent/projections-unavailable', - message: expect.stringContaining('sessionProjections') as unknown as string, - }) - - listChildren.mockRejectedValue(new Error('disk gone')) - await expect(subagents.remoteExportList(PARENT, signal)) - .rejects.toMatchObject({ code: 'gateway/internal', message: 'subagent catalog read failed' }) - }) -}) - describe('subagent prompt Remote', () => { it('rejects empty parent and child ids before delivery', async () => { const { subagents } = await bench({ [PARENT]: { status: 'idle' } }) @@ -259,7 +183,7 @@ describe('subagent prompt Remote', () => { await expect(subagents.prompt(promptRequest('Asia/Shanghai'), signal)) .resolves.toEqual({ messageId: 'm-1' }) expect(delivery).toHaveBeenCalledWith( - { status: 'idle' }, + expect.objectContaining({ status: 'idle' }), CHILD, [{ type: 'text', text: 'continue' }], { kind: 'user', rpcId: REQUEST_ID, clientTimeZone: 'Asia/Shanghai' }, @@ -361,7 +285,11 @@ describe('subagent interrupt Remote', () => { [CHILD, SessionId('')], ] as const) { const field = childSessionId.length === 0 ? 'childSessionId' : 'parentSessionId' - expect(() => subagents.interruptByParent(childSessionId, parentSessionId, 'continuable')) + expect(() => subagents.interruptByParent( + childSessionId, + parentSessionId, + 'continuable', + )) .toThrow(expect.objectContaining(emptyIdFailure('subagent.interrupt', field))) } expect(interrupt).not.toHaveBeenCalled() @@ -371,8 +299,15 @@ describe('subagent interrupt Remote', () => { const { subagents } = await bench() const interrupt = vi.spyOn(subagents, 'interrupt').mockReturnValue() - expect(subagents.interruptByParent(CHILD, PARENT, 'continuable')).toEqual({ accepted: true }) - expect(interrupt).toHaveBeenCalledWith(CHILD, { kind: 'user', parentSessionId: PARENT }) + expect(subagents.interruptByParent( + CHILD, + PARENT, + 'continuable', + )).toEqual({ accepted: true }) + expect(interrupt).toHaveBeenCalledWith(CHILD, { + kind: 'user', + parentSessionId: PARENT, + }) }) it('answers a foreign address as unauthorized and everything else as internal', async () => { @@ -380,7 +315,11 @@ describe('subagent interrupt Remote', () => { const interrupt = vi.spyOn(subagents, 'interrupt') interrupt.mockImplementation(() => { throw new SubagentError('not yours', 'UNAUTHORIZED') }) - expect(() => subagents.interruptByParent(CHILD, PARENT, 'continuable')).toThrow( + expect(() => subagents.interruptByParent( + CHILD, + PARENT, + 'continuable', + )).toThrow( expect.objectContaining({ code: 'subagent/unauthorized', message: expect.any(String) as unknown as string, @@ -389,7 +328,11 @@ describe('subagent interrupt Remote', () => { ) interrupt.mockImplementation(() => { throw new Error('boom') }) - expect(() => subagents.interruptByParent(CHILD, PARENT, 'continuable')).toThrow( + expect(() => subagents.interruptByParent( + CHILD, + PARENT, + 'continuable', + )).toThrow( expect.objectContaining({ code: 'gateway/internal', message: 'subagent interrupt failed', details: {} }), ) }) diff --git a/packages/subagent/subagent/tests/list-children.spec.ts b/packages/subagent/subagent/tests/list-children.spec.ts index 2794f825bd..84bcd8d6be 100644 --- a/packages/subagent/subagent/tests/list-children.spec.ts +++ b/packages/subagent/subagent/tests/list-children.spec.ts @@ -1,8 +1,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' +import { mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { z } from 'zod' +import { dirname, join } from 'node:path' import { Context } from '@deepseek-ai/cordis' import { createUserMessage } from '@deepseek-ai/dsh-llm' import AgentLoop from '@deepseek-ai/dsh-agent-loop' @@ -10,10 +9,9 @@ import type { Agent } from '@deepseek-ai/dsh-agent' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' import SessionStore, { SessionLogOffset, SessionSeq, SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' -import type { SessionObservation } from '@deepseek-ai/dsh-session-query' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import { generationLogPath } from '../../../session/session-persistence-jsonl/src/format.ts' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' -import type { ProjectionDefinition } from '@deepseek-ai/dsh-session-projection' import SessionProjectionCache from '@deepseek-ai/dsh-session-projection-cache' import Storage from '@deepseek-ai/dsh-storage' import { @@ -24,7 +22,6 @@ import { } from '@deepseek-ai/dsh-storage-domain' import SubagentRuntime, { SUBAGENT_DESCRIPTOR_VERSION, - SubagentError, } from '@deepseek-ai/dsh-subagent' import * as SubagentSpawn from '@deepseek-ai/dsh-subagent-spawn-in-process' import * as SubagentFork from '@deepseek-ai/dsh-subagent-fork-in-process' @@ -49,13 +46,16 @@ afterEach(async () => { /** Boot the continuable stack with real JSONL session persistence. */ async function setup( script: Script, - options: { projectionCache?: boolean } = {}, + options: { projectionCache?: boolean; compression?: 'none' | 'zstd' } = {}, ) { const ctx = new Context() await mountAgentLoopTestDependencies(ctx) const root = mkdtempSync(join(tmpdir(), 'dsh-subagent-list-')) roots.push(root) - const persistence = await ctx.plugin(JsonlSessionPersistence, { root }) + const persistence = await ctx.plugin(JsonlSessionPersistence, { + root, + ...options.compression === undefined ? {} : { compression: options.compression }, + }) persistenceDisposers.push(() => persistence.dispose()) await ctx.plugin(AgentLoop, { agents: [] }) if (options.projectionCache === true) { @@ -81,14 +81,7 @@ async function setup( return { id: session.id, session } as Awaited> })() : await loop.create(SessionId('parent'), { provider: 'mock', model: 'mock' }) - return { ctx, parent } -} - -async function setupWithoutProjections(): Promise { - const ctx = new Context() - await ctx.plugin(SessionStore) - await ctx.plugin(SubagentRuntime) - return ctx + return { ctx, parent, root } } const testSignal = new AbortController().signal @@ -142,6 +135,26 @@ async function authorChild( return sessionId } +/** Minimal complete-turn child log with one descriptor payload. */ +function childEvents(descriptor: unknown): SessionEvent[] { + return [ + { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, + { + type: 'user/message', + seq: SessionSeq(1), + time: 2, + data: createUserMessage({ content: [{ type: 'text', text: 'work' }], source: { kind: 'user' } }), + surfaceOp: 'append', + }, + { type: 'subagent/descriptor', seq: SessionSeq(2), time: 3, data: descriptor }, + { type: 'turn/end', seq: SessionSeq(3), time: 4, data: { turn: 1, reason: { kind: 'completed' } } }, + ] as SessionEvent[] +} + +function descriptorPayload(label: string, version = SUBAGENT_DESCRIPTOR_VERSION) { + return { version, mode: 'continuable' as const, provider: 'spawn', label } +} + /** * Serve one cold session's point read (the open handle) with a transformed * header while the enumeration listing keeps reporting the stored original — @@ -170,962 +183,180 @@ function mutateStoredHeader( } } -/** Minimal complete-turn child log with one descriptor payload. */ -function childEvents(descriptor: unknown): SessionEvent[] { - return [ - { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { - type: 'user/message', - seq: SessionSeq(1), - time: 2, - data: createUserMessage({ content: [{ type: 'text', text: 'work' }], source: { kind: 'user' } }), - surfaceOp: 'append', - }, - { type: 'subagent/descriptor', seq: SessionSeq(2), time: 3, data: descriptor }, - { type: 'turn/end', seq: SessionSeq(3), time: 4, data: { turn: 1, reason: { kind: 'completed' } } }, - ] as SessionEvent[] -} - -function descriptorPayload(label: string, version = SUBAGENT_DESCRIPTOR_VERSION) { - return { version, mode: 'continuable' as const, provider: 'spawn', label } -} - -declare module '@deepseek-ai/dsh-session-projection/types' { - interface SessionProjectionStateMap { - subagentListHostileProbe: { poisoned?: boolean | undefined } - } - interface SessionProjectionMap { - /** Test-only hostile probe proving per-child isolation of foreign unit failures. */ - subagentListHostileProbe: null - } -} - -/** - * A foreign registered unit that rejects one specific child's log at view - * time: `apply` never throws (the eager drive passes every committed event - * through it), while the poisoned state detonates only when a listing read - * folds or serves this child through the registry. - */ -const hostileProjectionDefinition = { - key: 'subagentListHostileProbe', - stateSchema: z.object({ poisoned: z.boolean().optional() }), - init: () => ({}), - apply: (state, event) => - event.type === 'subagent/descriptor' && (event.data as { label?: string }).label === 'poison me' - ? { poisoned: true } - : state, - wire: { - viewSchema: z.null(), - view: (state) => { - if (state.poisoned === true) throw new Error('hostile unit rejects the poisoned log') - return null - }, - }, - stateVersion: 1, -} satisfies ProjectionDefinition<'subagentListHostileProbe', { poisoned?: boolean | undefined }> - describe('SubagentRuntime.listChildren', () => { - it('lists live children without persistence or the continuation runtime', async () => { - const ctx = new Context() - await ctx.plugin(SessionStore) - await ctx.plugin(SessionProjectionRegistry) - await ctx.plugin(TestSessionQuery) - await ctx.plugin(SubagentRuntime) - expect(ctx.get('jobs')).toBeUndefined() - expect(ctx.get('agents')).toBeUndefined() - expect(ctx.get('sessionPersistence')).toBeUndefined() - - const parentId = SessionId('live-only-parent') - ctx.sessions.create(parentId) - const childId = SessionId('live-only-child') - const child = ctx.sessions.create(childId, { - meta: { parentSession: parentId, origin: 'subagent' }, + it('lists historical children through a migrated parent while preserving V3 files', async () => { + const { ctx, root } = await setup([], { compression: 'none' }) + const parent = SessionId('historical-parent') + const child = SessionId('historical-child') + const header = { type: 'session', version: 3, id: parent, createdAt: 1, isSeeded: false, delegationDepth: 0 } + const source = [ + [header, []], + [{ ...header, id: child, createdAt: 2, origin: 'subagent', parentSession: parent, delegationDepth: 1 }, [{ + type: 'subagent/descriptor', seq: 0, time: 2, + data: { version: 3, mode: 'continuable', provider: 'spawn', label: 'historical child' }, + }]], + ] as const + const originals = source.map(([meta, events]) => { + const path = generationLogPath(root, undefined, meta.id, 3, 'none') + const content = [meta, ...events].map(row => JSON.stringify(row)).join('\n') + '\n' + mkdirSync(dirname(path), { recursive: true }) + writeFileSync(path, content) + return { path, content } }) - child.append('turn/start', { - turn: 1, - }) - child.append('subagent/descriptor', descriptorPayload('live-only child')) - await expect(ctx.subagents.listChildren(parentId)).resolves.toEqual([ - { - kind: 'child', id: childId, label: 'live-only child', mode: 'continuable', - activity: 'running', hasChildren: false, - }, - ]) + expect(await ctx.subagents.listChildren(parent)).toEqual([{ + id: child, createdAt: 2, mode: 'continuable', label: 'historical child', + }]) + for (const { path, content } of originals) { + expect(readFileSync(path, 'utf8')).toBe(content) + expect(readdirSync(dirname(path))).toEqual(['session.v3.jsonl']) + } }) - it('fails loud when the projection registry is not mounted, even with no children', async () => { - const ctx = await setupWithoutProjections() - await expect(ctx.subagents.listChildren(SessionId('no-projections-parent'))).rejects.toThrow( - expect.objectContaining({ code: 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE' }) as Error, - ) - }) - - it('fails loud when the session store is not mounted', async () => { - const ctx = new Context() - await ctx.plugin(SessionProjectionRegistry) - await ctx.plugin(SubagentRuntime) - await expect(ctx.subagents.listChildren(SessionId('no-store-parent'))).rejects.toThrow( - expect.objectContaining({ code: 'SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE' }) as Error, - ) - }) - - it('fails loud when the Session query service is not mounted', async () => { - const ctx = new Context() - await ctx.plugin(SessionStore) - await ctx.plugin(SessionProjectionRegistry) - await ctx.plugin(SubagentRuntime) - - await expect(ctx.subagents.listChildren(SessionId('no-query-parent'))).rejects.toThrow( - expect.objectContaining({ code: 'SUBAGENT_CONTROL_QUERY_UNAVAILABLE' }) as Error, - ) - }) - - it('lists a persisted continuable child as inactive with its durable label', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const childId = await startChild(ctx, parent, 'summarize the doc') - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([ - { - kind: 'child', id: childId, label: 'summarize the doc', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }, - ]) - }) - - it('lists one-shot and continuable children under the same parent', async () => { + it('lists provider-established children from the parent catalog without a corpus or child read', async () => { const { ctx, parent } = await setup([textResponse('once'), textResponse('again')]) const oneShot = await ctx.subagents.start('spawn', { prompt: [{ type: 'text', text: 'finish once' }], + agentOptions: { model: 'child-model' }, parent, - signal: new AbortController().signal, + signal: testSignal, }) const oneShotId = oneShot.id await oneShot.result await oneShot.dispose() const continuableId = await startChild(ctx, parent, 'continuable child') + const listSessions = vi.spyOn(ctx.sessionQuery, 'listSessions') + const observeSession = vi.spyOn(ctx.sessionQuery, 'observeSession') - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toHaveLength(2) - expect(entries).toContainEqual({ - kind: 'child', - id: oneShotId, - mode: 'one-shot', - activity: 'inactive', - hasChildren: false, - }) - expect(entries).toContainEqual({ - kind: 'child', - id: continuableId, - label: 'continuable child', - mode: 'continuable', - activity: 'inactive', - hasChildren: false, - }) - }) - - it('accepts a persisted (non-live) parent target after restart', async () => { - const { ctx } = await setup([]) - // A parent that exists only in persistence — the restart shape. - const coldParent = SessionId('00000000-0000-4000-8000-00000000cccc') - await seedStoredSession(ctx.sessionPersistence, { - version: SESSION_FORMAT_VERSION, - id: coldParent, - createdAt: 1, - isSeeded: false, - }, [ - { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'turn/end', seq: SessionSeq(1), time: 2, data: { turn: 1, reason: { kind: 'completed' } } }, - ] as SessionEvent[]) - const childId = await authorChild(ctx, '00000000-0000-4000-8000-00000000cdcd', { - parentSession: coldParent, - origin: 'subagent', - }, childEvents(descriptorPayload('persisted parent case'))) - const entries = await ctx.subagents.listChildren(coldParent) - expect(entries).toEqual([ - { - kind: 'child', id: childId, label: 'persisted parent case', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }, + const children = await ctx.subagents.listChildren(parent.id) + expect(children.map(({ createdAt: _createdAt, ...child }) => child)).toEqual([ + { id: oneShotId, mode: 'one-shot' }, + { id: continuableId, label: 'continuable child', mode: 'continuable' }, ]) + expect(children.every(child => Number.isFinite(child.createdAt))).toBe(true) + expect(listSessions).not.toHaveBeenCalled() + expect(observeSession).toHaveBeenCalledOnce() }) - it('orders children by createdAt then id without listing ordinary forks', async () => { + it('releases its observation after reading the catalog view', async () => { const { ctx, parent } = await setup([]) - /** Publish one live child with a pinned header ordering key. */ - const liveChild = (parentId: SessionId, id: string, createdAt: number, label: string): SessionId => { - const session = ctx.sessions.create(SessionId(id), { - meta: { parentSession: parentId, origin: 'subagent', createdAt }, - }) - session.append('turn/start', { turn: 1 }) - session.append('subagent/descriptor', descriptorPayload(label)) - return session.header.id - } - // Live creation order is deliberately shuffled against the expected - // result: same-createdAt ties break on id, different createdAt orders - // ascending. - const late = liveChild(parent.id, '00000000-0000-4000-8000-000000000009', 9, 'late child') - const tieB = liveChild(parent.id, '00000000-0000-4000-8000-000000000002', 5, 'tie b') - const tieA = liveChild(parent.id, '00000000-0000-4000-8000-000000000001', 5, 'tie a') - // An ordinary session fork shares parentSession but has no subagent origin. - const fork = ctx.sessions.fork(parent.session, undefined, SessionId('plain-fork')) - await ctx.sessions.flush(fork) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries.map(entry => entry.id)).toEqual([tieA, tieB, late]) - expect(entries.every(entry => entry.kind === 'child')).toBe(true) - }) - - it('omits a live child that has not appended its descriptor yet', async () => { - const { ctx, parent } = await setup([]) - const pending = ctx.sessions.create(SessionId('creation-window-child'), { - meta: { parentSession: parent.id, origin: 'subagent' }, + const childId = SessionId('cold-state-child') + parent.session.append('subagent/catalog', { + version: 0, + childId, + childCreatedAt: 3, + mode: 'one-shot', + label: 'state child', }) - pending.append('turn/start', { turn: 1 }) - // The creation window: the establishing provider has not appended the - // descriptor yet, so the row is omitted rather than diagnosed. - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([]) - }) - - it('contains a live child projection failure as one corrupt diagnostic', async () => { - const { ctx, parent } = await setup([]) - const childId = SessionId('live-projection-failure') - const child = ctx.sessions.create(childId, { - meta: { parentSession: parent.id, origin: 'subagent' }, - }) - child.append('subagent/descriptor', descriptorPayload('broken live child')) - const snapshot = ctx.sessionProjections.snapshot.bind(ctx.sessionProjections) - vi.spyOn(ctx.sessionProjections, 'snapshot').mockImplementation((session, keys) => { - if (session.id === childId) throw new Error('projection failed') - return snapshot(session, keys) - }) - - await expect(ctx.subagents.listChildren(parent.id)).resolves.toContainEqual({ - kind: 'diagnostic', id: childId, reason: 'corrupt', - }) - }) - - it('maps a non-Error cold observation failure to unavailable', async () => { - const { ctx, parent } = await setup([]) - const childId = await authorChild(ctx, '00000000-0000-4000-8000-00000000aa01', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('unreadable child'))) - const observe = ctx.sessionQuery.observeSession.bind(ctx.sessionQuery) - vi.spyOn(ctx.sessionQuery, 'observeSession').mockImplementation((id, options) => { - if (id === childId) { - return Promise.reject('backend unavailable') // oxlint-disable-line typescript/prefer-promise-reject-errors - } - return observe(id, options) - }) - - await expect(ctx.subagents.listChildren(parent.id)).resolves.toContainEqual({ - kind: 'diagnostic', id: childId, reason: 'unavailable', - }) - }) - - it('releases a cold observation when cancellation lands after its read', async () => { - const { ctx, parent } = await setup([]) - const controller = new AbortController() - const childId = await authorChild(ctx, '00000000-0000-4000-8000-00000000aa02', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('cancelled child'))) + using observed = await ctx.sessionQuery.observeSession(parent.id) const dispose = vi.fn() - vi.spyOn(ctx.sessionQuery, 'observeSession').mockImplementation((id) => { - if (id !== childId) throw new Error(`unexpected observation: ${id}`) - controller.abort(new Error('cancelled after observation')) - return Promise.resolve({ - source: 'prepared', - header: { - version: SESSION_FORMAT_VERSION, - id: childId, - createdAt: 1, - parentSession: parent.id, - origin: 'subagent', - }, - events: [], - cursor: -1, - projections: { asOfSeq: -1, values: {} }, - retain: vi.fn(), - [Symbol.dispose]: dispose, - } as unknown as SessionObservation) + vi.spyOn(ctx.sessionQuery, 'observeSession').mockResolvedValue({ + ...observed, + [Symbol.dispose]: dispose, }) - - await expect(ctx.subagents.listChildren(parent.id, controller.signal)) - .rejects.toMatchObject({ code: 'CANCELLED' }) + expect(await ctx.subagents.listChildren(parent.id)).toEqual([{ + id: childId, createdAt: 3, label: 'state child', mode: 'one-shot', + }]) expect(dispose).toHaveBeenCalledOnce() }) - it('lists a one-shot child with its durable creation label', async () => { + it('releases the observation when its catalog projection is unavailable', async () => { const { ctx, parent } = await setup([]) - const labeled = await authorChild(ctx, '00000000-0000-4000-8000-00000000ab02', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents({ - version: SUBAGENT_DESCRIPTOR_VERSION, + using observed = await ctx.sessionQuery.observeSession(parent.id, { projectionMode: 'none' }) + const dispose = vi.fn() + vi.spyOn(ctx.sessionQuery, 'observeSession').mockResolvedValue({ ...observed, [Symbol.dispose]: dispose }) + await expect(ctx.subagents.listChildren(parent.id)).rejects.toMatchObject({ + code: 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE', + }) + expect(dispose).toHaveBeenCalledOnce() + }) + + it('forwards cancellation and preserves query failures', async () => { + const { ctx, parent } = await setup([]) + const controller = new AbortController() + controller.abort(new Error('cancel catalog')) + await expect(ctx.subagents.listChildren(parent.id, controller.signal)).rejects.toMatchObject({ + code: 'SESSION_QUERY_ABORTED', + }) + const failure = new Error('parent read failed') + vi.spyOn(ctx.sessionQuery, 'observeSession').mockRejectedValue(failure) + await expect(ctx.subagents.listChildren(parent.id)).rejects.toBe(failure) + }) + + it('ignores inherited fork facts and accepts facts in the fork own suffix', async () => { + const ctx = new Context() + await ctx.plugin(SessionStore) + await ctx.plugin(SessionProjectionRegistry) + await ctx.plugin(TestSessionQuery) + await ctx.plugin(SubagentRuntime) + const ancestor = ctx.sessions.create(SessionId('catalog-ancestor')) + ancestor.append('turn/start', { turn: 1 }) + ancestor.append('subagent/catalog', { + version: 0, + childId: SessionId('inherited-child'), + childCreatedAt: 1, mode: 'one-shot', - provider: 'spawn', - label: 'labeled one-shot', - })) - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([ - { - kind: 'child', id: labeled, mode: 'one-shot', label: 'labeled one-shot', - activity: 'inactive', hasChildren: false, - }, - ]) - }) - - it('reports a live child as running while keeping settled siblings complete', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const settled = await startChild(ctx, parent, 'settled child') - // A live child session outside persistence: publish a live session with a - // descriptor and the parent lineage, without starting an Activation. - const liveId = SessionId('live-child') - const live = ctx.sessions.create(liveId, { - meta: { parentSession: parent.id, origin: 'subagent' }, }) - live.append('turn/start', { turn: 1 }) - live.append('subagent/descriptor', descriptorPayload('live child')) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toContainEqual({ - kind: 'child', id: settled, label: 'settled child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - expect(entries).toContainEqual({ - kind: 'child', id: liveId, label: 'live child', mode: 'continuable', - activity: 'running', hasChildren: false, - }) - }) - - it('lists the last descriptor when a log carries more than one', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const healthy = await startChild(ctx, parent, 'healthy sibling') - const events = childEvents(descriptorPayload('twice')) - events.splice(3, 0, { - type: 'subagent/descriptor', - seq: SessionSeq(3), - time: 3, - data: descriptorPayload('twice again'), - } as SessionEvent) - events[4] = { ...events[4]!, seq: SessionSeq(4) } - const doubled = await authorChild(ctx, '00000000-0000-4000-8000-00000000dupe', { - parentSession: parent.id, - origin: 'subagent', - }, events) - // The last-wins projection fold serves the final descriptor's identity; a - // repeated descriptor is not a per-child corruption diagnostic. - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toContainEqual({ - kind: 'child', id: doubled, label: 'twice again', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - expect(entries).toContainEqual({ - kind: 'child', id: healthy, label: 'healthy sibling', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - }) - - it('serves the serializable null sentinel when a later descriptor invalidates the identity', async () => { - const { ctx, parent } = await setup([]) - const liveId = SessionId('invalidated-live-child') - const live = ctx.sessions.create(liveId, { - meta: { parentSession: parent.id, origin: 'subagent' }, - }) - live.append('turn/start', { turn: 1 }) - live.append('subagent/descriptor', descriptorPayload('was valid')) - expect(ctx.sessionProjections.snapshot(live).values.subagent) - .toEqual({ mode: 'continuable', label: 'was valid', seq: SessionSeq(1) }) - // Last-wins: the malformed follow-up resets the identity to the sentinel. - live.append( - 'subagent/descriptor', - { version: SUBAGENT_DESCRIPTOR_VERSION, mode: 'continuable', provider: 7 } as never, - ) - const values = ctx.sessionProjections.snapshot(live).values - expect(values.subagent).toBeNull() - // The sentinel survives a JSON push frame; an undefined field would be - // dropped there and a consumer would keep the stale identity forever. - const wired = JSON.parse(JSON.stringify(values)) as Record - expect('subagent' in wired).toBe(true) - expect(wired['subagent']).toBeNull() - // The listing reads the same null as no value: running → omitted. - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([]) - }) - - it('diagnoses a settled child whose later descriptor invalidated the identity as corrupt', async () => { - const { ctx, parent } = await setup([]) - const events = childEvents(descriptorPayload('was valid')) - events.splice(3, 0, { - type: 'subagent/descriptor', - seq: SessionSeq(3), - time: 3, - data: { version: SUBAGENT_DESCRIPTOR_VERSION, mode: 'continuable', provider: 7 }, - } as unknown as SessionEvent) - events[4] = { ...events[4]!, seq: SessionSeq(4) } - const invalidated = await authorChild(ctx, '00000000-0000-4000-8000-00000000ad01', { - parentSession: parent.id, - origin: 'subagent', - }, events) - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([ - { kind: 'diagnostic', id: invalidated, reason: 'corrupt' }, - ]) - }) - - it('serves a cached own-suffix identity directly without inspection', async () => { - const { ctx, parent } = await setup([], { projectionCache: true }) - const child = await authorChild(ctx, '00000000-0000-4000-8000-00000000ae01', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('disk label'))) - // seq 2 >= seedLength 0: the cached identity provably comes from the - // child's own suffix, so it is final and the log is never re-read — the - // divergent label proves the row, not the log, produced the entry. - ctx.sessionProjectionCache.cachedSnapshot = () => ({ - asOfSeq: SessionSeq(2), - values: { subagent: { mode: 'continuable', label: 'cached own', seq: SessionSeq(2) } }, - }) - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: child, label: 'cached own', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - expect(inspect).not.toHaveBeenCalled() - }) - - it('refuses a cached ancestor identity from the fork seed and lets preparation rule', async () => { - const { ctx, parent } = await setup([], { projectionCache: true }) - // A fork child: the seed replays the ancestor's descriptor (seq 2), and - // the child's own descriptor arrives in its first own turn (seq 5). - const seed = childEvents(descriptorPayload('ancestor label')) - const events = [ - ...seed, - { type: 'turn/start', seq: SessionSeq(4), time: 5, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'subagent/descriptor', seq: SessionSeq(5), time: 6, data: descriptorPayload('own label') }, - { type: 'turn/end', seq: SessionSeq(6), time: 7, data: { turn: 2, reason: { kind: 'completed' } } }, - ] as SessionEvent[] - const forkChild = await authorChild(ctx, '00000000-0000-4000-8000-00000000ae02', { - parentSession: parent.id, - origin: 'subagent', - }, events, seed.length) - // A creation-window checkpoint carried the ANCESTOR identity: its seq 2 - // fails the own-suffix gate (< seedLength 4), so preparation rules. - ctx.sessionProjectionCache.cachedSnapshot = () => ({ - asOfSeq: SessionSeq(2), - values: { subagent: { mode: 'continuable', label: 'ancestor label', seq: SessionSeq(2) } }, - }) - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: forkChild, label: 'own label', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - expect(inspect).toHaveBeenCalledTimes(1) - }) - - it.each([ - ['id', (meta: SessionHeader): SessionHeader => ({ ...meta, id: SessionId('another-lifecycle') })], - ['createdAt', (meta: SessionHeader): SessionHeader => ({ ...meta, createdAt: meta.createdAt + 1 })], - ['cwd', (meta: SessionHeader): SessionHeader => ({ ...meta, cwd: '/elsewhere' })], - ['parentSession', (meta: SessionHeader): SessionHeader => ({ ...meta, parentSession: SessionId('another-parent') })], - ['isSeeded', (meta: SessionHeader): SessionHeader => ({ ...meta, isSeeded: !meta.isSeeded })], - ['delegationDepth', (meta: SessionHeader): SessionHeader => ({ ...meta, delegationDepth: (meta.delegationDepth ?? 0) + 1 })], - ] as const)('diagnoses an inspection returning another lifecycle (%s) as corrupt', async (_field, mutate) => { - const { ctx, parent } = await setup([textResponse('done')]) - const healthy = await startChild(ctx, parent, 'healthy sibling') - const reborn = await authorChild(ctx, '00000000-0000-4000-8000-00000000ae03', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('reborn child'))) - // The id was re-published as a different lifecycle after enumeration. - mutateStoredHeader(ctx, reborn, mutate) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toContainEqual({ kind: 'diagnostic', id: reborn, reason: 'corrupt' }) - expect(entries).toContainEqual({ - kind: 'child', id: healthy, label: 'healthy sibling', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - }) - - it('lets preparation rule when the cache serves the null sentinel', async () => { - const { ctx, parent } = await setup([], { projectionCache: true }) - const healthy = await authorChild(ctx, '00000000-0000-4000-8000-00000000ad02', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('actually valid'))) - // A stale cached sentinel must not out-rank the authoritative re-fold. - ctx.sessionProjectionCache.cachedSnapshot = () => ({ asOfSeq: SessionSeq(0), values: { subagent: null } }) - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: healthy, label: 'actually valid', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - expect(inspect).toHaveBeenCalledTimes(1) - }) - - it('maps a child rejected by persistence validation to corrupt', async () => { - const { ctx, parent } = await setup([]) - // The canonical envelope contains a message without an id; persistence - // adoption rejects it before any projection fold can run. - const invalid = await authorChild(ctx, '00000000-0000-4000-8000-0000000000ee', { - parentSession: parent.id, - origin: 'subagent', - }, [ - { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { - type: 'user/message', - seq: SessionSeq(1), - time: 2, - data: { role: 'user', content: [{ type: 'text', text: 'work' }], source: { kind: 'user' } }, - surfaceOp: 'append', - }, - { type: 'subagent/descriptor', seq: SessionSeq(2), time: 3, data: descriptorPayload('broken message') }, - ] as SessionEvent[]) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([{ kind: 'diagnostic', id: invalid, reason: 'corrupt' }]) - }) - - it('diagnoses a malformed descriptor payload as corrupt', async () => { - const { ctx, parent } = await setup([]) - const malformed = await authorChild(ctx, '00000000-0000-4000-8000-0000000000ff', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents({ version: SUBAGENT_DESCRIPTOR_VERSION, mode: 'continuable', provider: 7 })) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([{ kind: 'diagnostic', id: malformed, reason: 'corrupt' }]) - }) - - it('diagnoses an unknown descriptor version as corrupt', async () => { - const { ctx, parent } = await setup([]) - const future = await authorChild(ctx, '00000000-0000-4000-8000-0000000000aa', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('from the future', SUBAGENT_DESCRIPTOR_VERSION + 1))) - // The projection fold does not distinguish an unrecognized version from - // other invalid descriptors: both serve no identity, and a settled - // no-value candidate is corrupt. - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([{ kind: 'diagnostic', id: future, reason: 'corrupt' }]) - }) - - it('rejects a fork whose only descriptor belongs to its inherited seed', async () => { - const { ctx, parent } = await setup([]) - // A seed-replayed descriptor predates this child's own suffix and cannot - // identify the fork as a resumable child. - const seed = childEvents(descriptorPayload('ancestor label')) - const forkChild = await authorChild(ctx, '00000000-0000-4000-8000-0000000000f0', { - parentSession: parent.id, - origin: 'subagent', - }, seed, seed.length) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([{ kind: 'diagnostic', id: forkChild, reason: 'corrupt' }]) - }) - - it('does not filter by provider availability: children of unmounted providers stay listed', async () => { - const { ctx, parent } = await setup([]) - const foreign = await authorChild(ctx, '00000000-0000-4000-8000-0000000000bb', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents({ - version: SUBAGENT_DESCRIPTOR_VERSION, + ancestor.append('turn/end', { turn: 1, reason: { kind: 'completed' } }) + const fork = ctx.sessions.fork(ancestor, undefined, SessionId('catalog-fork')) + fork.append('subagent/catalog', { + version: 0, + childId: SessionId('own-child'), + childCreatedAt: 2, mode: 'continuable', - provider: 'not-mounted', - label: 'orphan provider', - })) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([ - { - kind: 'child', id: foreign, label: 'orphan provider', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }, - ]) + label: 'own', + }) + + expect(await ctx.subagents.listChildren(fork.id)).toEqual([{ + id: SessionId('own-child'), createdAt: 2, mode: 'continuable', label: 'own', + }]) }) - it('contains a foreign unit failure during a cold fold to that child as corrupt', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - ctx.sessionProjections.register(hostileProjectionDefinition) - const healthy = await startChild(ctx, parent, 'healthy sibling') - const poisoned = await authorChild(ctx, '00000000-0000-4000-8000-00000000d00d', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('poison me'))) - // The subagent unit itself folds this child cleanly; the FOREIGN unit's - // view throws, and that damage stays contained to the one child. - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toContainEqual({ kind: 'diagnostic', id: poisoned, reason: 'corrupt' }) - expect(entries).toContainEqual({ - kind: 'child', id: healthy, label: 'healthy sibling', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - }) - - it('does not evaluate an unrelated wire view when exposing a live child identity', async () => { - const { ctx, parent } = await setup([]) - ctx.sessionProjections.register(hostileProjectionDefinition) - const poisonedId = SessionId('live-poisoned-child') - const poisoned = ctx.sessions.create(poisonedId, { - meta: { parentSession: parent.id, origin: 'subagent' }, - }) - poisoned.append('turn/start', { turn: 1 }) - poisoned.append('subagent/descriptor', descriptorPayload('poison me')) - const healthyId = SessionId('live-healthy-child') - const healthy = ctx.sessions.create(healthyId, { - meta: { parentSession: parent.id, origin: 'subagent' }, - }) - healthy.append('turn/start', { turn: 1 }) - healthy.append('subagent/descriptor', descriptorPayload('live healthy')) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toContainEqual({ - kind: 'child', id: poisonedId, label: 'poison me', mode: 'continuable', - activity: 'running', hasChildren: false, - }) - expect(entries).toContainEqual({ - kind: 'child', id: healthyId, label: 'live healthy', mode: 'continuable', - activity: 'running', hasChildren: false, - }) - }) - - it('fails the whole enumeration when the persisted listing itself fails', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - await startChild(ctx, parent, 'never listed') - ctx.sessionPersistence.list = () => Promise.reject(new Error('backend listing failed')) - // Without any abort in flight, the original backend failure propagates - // as the operation failure — no cancellation mapping, no diagnostic rows. - await expect(ctx.subagents.listChildren(parent.id)).rejects.toThrow('backend listing failed') - }) - - it('maps a failed cold inspection to one unavailable diagnostic and retries it next listing', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const healthy = await startChild(ctx, parent, 'healthy sibling') - const flaky = await authorChild(ctx, '00000000-0000-4000-8000-00000000f1a7', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('flaky storage'))) - const original = ctx.sessionPersistence.open.bind(ctx.sessionPersistence) - ctx.sessionPersistence.open = (sessionId, access, options) => { - if (sessionId === flaky) { - return Promise.reject(new Error('backend read failed')) - } - return original(sessionId, access, options) + it('bounds chunk growth and ignores more than 1,000 unrelated Sessions', async () => { + const ctx = new Context() + await ctx.plugin(SessionStore) + await ctx.plugin(SessionProjectionRegistry) + await ctx.plugin(TestSessionQuery) + await ctx.plugin(SubagentRuntime) + const parent = ctx.sessions.create(SessionId('chunk-parent')) + for (let index = 0; index < 1_001; index += 1) { + ctx.sessions.create(SessionId(`unrelated-${String(index).padStart(4, '0')}`)) } - // Per-child isolation: the failed child degrades to one diagnostic while - // the healthy sibling stays complete. - const degraded = await ctx.subagents.listChildren(parent.id) - expect(degraded).toContainEqual({ kind: 'diagnostic', id: flaky, reason: 'unavailable' }) - expect(degraded).toContainEqual({ - kind: 'child', id: healthy, label: 'healthy sibling', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - // Nothing is memoized: with the backend healthy again, the next listing - // folds the same child to its identity. - ctx.sessionPersistence.open = original - await expect(ctx.subagents.listChildren(parent.id)).resolves.toContainEqual({ - kind: 'child', id: flaky, label: 'flaky storage', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }) - }) - - it('lists compacted and uncompacted children identically', async () => { - const { ctx, parent } = await setup([]) - const plain = await authorChild(ctx, '00000000-0000-4000-8000-00000000c0de', { - parentSession: parent.id, - createdAt: 1, - origin: 'subagent', - }, childEvents(descriptorPayload('twin child'))) - // The compacted twin: a compaction checkpoint replaces the whole surface, - // while the append-only log retains the model-hidden descriptor event. - const compactedEvents = childEvents(descriptorPayload('twin child')) - compactedEvents.push({ - type: 'user/message', - seq: SessionSeq(4), - time: 5, - data: createUserMessage({ - content: [{ type: 'text', text: 'summary of everything' }], - source: { kind: 'plugin', plugin: 'compact' }, - }), - surfaceOp: { op: 'replace', startSeq: SessionSeq(1), endSeq: SessionSeq(1) }, - sourceEventSeqs: [SessionSeq(1)], - }) - const compacted = await authorChild(ctx, '00000000-0000-4000-8000-00000000c1de', { - parentSession: parent.id, - createdAt: 2, - origin: 'subagent', - }, compactedEvents) - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([ - { - kind: 'child', id: plain, label: 'twin child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }, - { - kind: 'child', id: compacted, label: 'twin child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }, - ]) - }) - - it('reports an origin-classified grandchild without inspecting it', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const childId = await startChild(ctx, parent, 'direct child') - const grandchildId = await authorChild(ctx, '00000000-0000-4000-8000-0000000000cc', { - parentSession: childId, - origin: 'subagent', - }, childEvents(descriptorPayload('grandchild'))) - const inspected: SessionId[] = [] - const original = ctx.sessionPersistence.open.bind(ctx.sessionPersistence) - ctx.sessionPersistence.open = (sessionId, access, options) => { - inspected.push(sessionId) - return original(sessionId, access, options) - } - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toEqual([ - { - kind: 'child', id: childId, label: 'direct child', mode: 'continuable', - activity: 'inactive', hasChildren: true, - }, - ]) - // The grandchild contributes only its header to the hasChildren hint. - expect(inspected).toContain(childId) - expect(inspected).not.toContain(grandchildId) - }) - - it('inspects each cold child exactly once and a live child never', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const coldStarted = await startChild(ctx, parent, 'cold started child') - const coldAuthored = await authorChild(ctx, '00000000-0000-4000-8000-00000000ab01', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('cold authored child'))) - const liveId = SessionId('live-mixed-child') - const live = ctx.sessions.create(liveId, { - meta: { parentSession: parent.id, origin: 'subagent' }, - }) - live.append('turn/start', { turn: 1 }) - live.append('subagent/descriptor', descriptorPayload('live mixed child')) - - const inspected: SessionId[] = [] - const original = ctx.sessionPersistence.open.bind(ctx.sessionPersistence) - ctx.sessionPersistence.open = (sessionId, access, options) => { - inspected.push(sessionId) - return original(sessionId, access, options) - } - const entries = await ctx.subagents.listChildren(parent.id) - expect(entries).toHaveLength(3) - // The cost model: one inspection per cold child, none for a live child, - // whose identity is served from the registry's watermark cache. - expect(inspected.filter(id => id === coldStarted)).toHaveLength(1) - expect(inspected.filter(id => id === coldAuthored)).toHaveLength(1) - expect(inspected).not.toContain(liveId) - }) - - it('serves a cold child from the projection cache without any inspection', async () => { - const { ctx, parent } = await setup([textResponse('done')], { projectionCache: true }) - const childId = await startChild(ctx, parent, 'cached child') - // The child's turn/end and disposal are the cache's mandatory checkpoint - // points; both writes are fail-soft asynchronous, so wait for the row. - const header = (await ctx.sessionPersistence.list()).find(snapshot => snapshot.header.id === childId)?.header - await vi.waitFor(() => { - expect(ctx.sessionProjectionCache.cachedSnapshot(header!, SessionLogOffset(0))?.values.subagent).toBeDefined() - }, { timeout: 5_000 }) - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: childId, label: 'cached child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - expect(inspect).not.toHaveBeenCalled() - }) - - it('falls back to inspection when the cache serves no identity for the child', async () => { - const { ctx, parent } = await setup([], { projectionCache: true }) - const foreign = await authorChild(ctx, '00000000-0000-4000-8000-00000000ac01', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('uncached child'))) - const expected = [{ - kind: 'child', id: foreign, label: 'uncached child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }] - // No stored row at all for a foreign child this process never ran. - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual(expected) - expect(inspect).toHaveBeenCalledTimes(1) - // A stored row whose cut predates the descriptor: the subagent key is - // absent from the served values, and preparation still rules. - ctx.sessionProjectionCache.cachedSnapshot = () => ({ asOfSeq: SessionSeq(0), values: {} }) - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual(expected) - expect(inspect).toHaveBeenCalledTimes(2) - }) - - it('takes the preparation rung directly when no projection cache is mounted', async () => { - const { ctx, parent } = await setup([]) - expect(ctx.get('sessionProjectionCache')).toBeUndefined() - const foreign = await authorChild(ctx, '00000000-0000-4000-8000-00000000ac02', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('uncacheable child'))) - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: foreign, label: 'uncacheable child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - expect(inspect).toHaveBeenCalledTimes(1) - }) - - it('silently falls through to preparation when the cache read throws', async () => { - const { ctx, parent } = await setup([], { projectionCache: true }) - const recovered = await authorChild(ctx, '00000000-0000-4000-8000-00000000ac03', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('recovered child'))) - ctx.sessionProjectionCache.cachedSnapshot = () => { - // A poisoned stored row (any unit's) detonates at view time; the cache - // is derived data, so its failure must not become a verdict. - throw new Error('poisoned cache row') - } - const inspect = vi.spyOn(ctx.sessionPersistence, 'open') - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: recovered, label: 'recovered child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - expect(inspect).toHaveBeenCalledTimes(1) - }) - - it('does not count an ordinary grandchild without subagent origin', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const childId = await startChild(ctx, parent, 'direct child') - await authorChild(ctx, '00000000-0000-4000-8000-0000000000f1', { - parentSession: childId, - }, [ - { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'turn/end', seq: SessionSeq(1), time: 2, data: { turn: 1, reason: { kind: 'completed' } } }, - ] as SessionEvent[]) - - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: childId, label: 'direct child', mode: 'continuable', - activity: 'inactive', hasChildren: false, - }]) - }) - - it('counts an origin-classified diagnostic grandchild', async () => { - const { ctx, parent } = await setup([textResponse('done')]) - const childId = await startChild(ctx, parent, 'direct child') - const diagnosticId = await authorChild(ctx, '00000000-0000-4000-8000-0000000000f2', { - parentSession: childId, - origin: 'subagent', - }, childEvents({ version: SUBAGENT_DESCRIPTOR_VERSION, mode: 'continuable', provider: 7 })) - - await expect(ctx.subagents.listChildren(childId)).resolves.toEqual([ - { kind: 'diagnostic', id: diagnosticId, reason: 'corrupt' }, - ]) - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([{ - kind: 'child', id: childId, label: 'direct child', mode: 'continuable', - activity: 'inactive', hasChildren: true, - }]) - }) - - it('a pre-aborted signal stops before any persistence read', async () => { - const { ctx, parent } = await setup([]) - const controller = new AbortController() - controller.abort() - ctx.sessionPersistence.list = () => Promise.reject(new Error('must not be called')) - await expect(ctx.subagents.listChildren(parent.id, controller.signal)).rejects.toThrow( - expect.objectContaining({ code: 'CANCELLED' }) as Error, - ) - }) - - it('forwards cancellation to the persisted listing and reports the stable subagent error', async () => { - const { ctx, parent } = await setup([]) - const controller = new AbortController() - const entered = Promise.withResolvers() - ctx.sessionPersistence.list = (options) => { - entered.resolve(undefined) - return new Promise((_resolve, reject) => { - options?.signal?.addEventListener('abort', () => { - reject(new Error('backend listing aborted')) - }, { once: true }) + for (let index = 0; index < 1_025; index += 1) { + parent.append('subagent/catalog', { + version: 0, + childId: SessionId(`child-${String(index).padStart(3, '0')}`), + childCreatedAt: index, + mode: 'one-shot', }) } - const listing = ctx.subagents.listChildren(parent.id, controller.signal) - await entered.promise - controller.abort() - await expect(listing).rejects.toThrow( - expect.objectContaining({ code: 'CANCELLED' }) as Error, - ) - }) - - it('forwards cancellation to a cold inspection and reports the stable subagent error', async () => { - const { ctx, parent } = await setup([]) - await authorChild(ctx, '00000000-0000-4000-8000-00000000ce11', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('cancelled cold read'))) - const controller = new AbortController() - const entered = Promise.withResolvers() - ctx.sessionPersistence.open = (_sessionId, _access, options) => { - entered.resolve(undefined) - return new Promise((_resolve, reject) => { - options?.signal?.addEventListener('abort', () => { - reject(new Error('backend read aborted')) - }, { once: true }) - }) + const listSessions = vi.spyOn(ctx.sessionQuery, 'listSessions') + const state = ctx.sessionProjections.stateOf(parent, 'subagentCatalog') + const chunkLengths: number[] = [] + for (let chunk = state?.head; chunk !== undefined; chunk = chunk.previous) { + chunkLengths.push(chunk.values.length) } - const listing = ctx.subagents.listChildren(parent.id, controller.signal) - await entered.promise - controller.abort() - await expect(listing).rejects.toThrow( - expect.objectContaining({ code: 'CANCELLED' }) as Error, - ) + expect(chunkLengths).toEqual([1, ...Array.from({ length: 16 }, () => 64)]) + const entries = await ctx.subagents.listChildren(parent.id) + expect(listSessions).not.toHaveBeenCalled() + expect(entries).toHaveLength(1_025) + expect(entries.find(entry => entry.id === 'child-064')).toEqual({ + id: SessionId('child-064'), createdAt: 64, mode: 'one-shot', + }) }) - it('an abort observed after a cold inspection resolves cannot become a successful result', async () => { - const { ctx, parent } = await setup([]) - await authorChild(ctx, '00000000-0000-4000-8000-00000000ce12', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('cancelled mid-listing'))) - const controller = new AbortController() - const original = ctx.sessionPersistence.open.bind(ctx.sessionPersistence) - ctx.sessionPersistence.open = async (sessionId, access, options) => { - const result = await original(sessionId, access, options) - controller.abort() - return result - } - // The post-read checkpoint throws the stable subagent error instead of - // interpreting the fully-read log as a successful listing. - await expect(ctx.subagents.listChildren(parent.id, controller.signal)) - .rejects.toThrow(expect.objectContaining({ code: 'CANCELLED' }) as Error) + it('fails loud when the query service is unavailable', async () => { + const withoutProjection = new Context() + await withoutProjection.plugin(SessionStore) + await withoutProjection.plugin(SubagentRuntime) + const parent = withoutProjection.sessions.create(SessionId('parent')) + await expect(withoutProjection.subagents.listChildren(parent.id)).rejects.toMatchObject({ + code: 'SUBAGENT_CONTROL_QUERY_UNAVAILABLE', + }) }) - it('a cold inspection failure during an abort cannot become an unavailable diagnostic', async () => { - const { ctx, parent } = await setup([]) - await authorChild(ctx, '00000000-0000-4000-8000-00000000ce13', { - parentSession: parent.id, - origin: 'subagent', - }, childEvents(descriptorPayload('aborted behind a failure'))) - const controller = new AbortController() - ctx.sessionPersistence.open = () => { - // The read fails while the caller aborts: cancellation normalization - // must fail the listing rather than return a one-diagnostic success. - controller.abort() - return Promise.reject(new Error('backend read failed')) - } - await expect(ctx.subagents.listChildren(parent.id, controller.signal)).rejects.toThrow( - expect.objectContaining({ code: 'CANCELLED' }) as Error, - ) - }) - it('returns an empty array for a parent with no children', async () => { - const { ctx, parent } = await setup([]) - await ctx.sessions.flush(parent.session) - await expect(ctx.subagents.listChildren(parent.id)).resolves.toEqual([]) - }) - - it('SubagentError from listChildren is typed with its stable code', async () => { - const ctx = await setupWithoutProjections() - const caught: unknown = await ctx.subagents.listChildren(SessionId('typed-no-projections-parent')) - .catch((error: unknown) => error) - expect(caught).toBeInstanceOf(SubagentError) - expect((caught as SubagentError).code).toBe('SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE') - }) }) - describe('SubagentRuntime.listDescendants', () => { it('flattens the complete tree in stable pre-order with verified parent and depth', async () => { const { ctx, parent } = await setup([]) @@ -1328,20 +559,200 @@ describe('SubagentRuntime.listDescendants', () => { ]) }) - it('verifies a cold candidate still belongs to its enumerated lifecycle', async () => { + it('fails loud when descendant enumeration lacks the Session store or query service', async () => { + const withoutStore = new Context() + await withoutStore.plugin(SessionProjectionRegistry) + await withoutStore.plugin(SubagentRuntime) + await expect(withoutStore.subagents.listDescendants(SessionId('no-store-parent'))).rejects.toMatchObject({ + code: 'SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE', + }) + + const withoutQuery = new Context() + await withoutQuery.plugin(SessionStore) + await withoutQuery.plugin(SessionProjectionRegistry) + await withoutQuery.plugin(SubagentRuntime) + await expect(withoutQuery.subagents.listDescendants(SessionId('no-query-parent'))).rejects.toMatchObject({ + code: 'SUBAGENT_CONTROL_QUERY_UNAVAILABLE', + }) + }) + + it('propagates a descendant corpus listing failure', async () => { const { ctx, parent } = await setup([]) - const childId = await authorChild(ctx, '00000000-0000-4000-8000-00000000ddd1', { - parentSession: parent.id, - createdAt: 1, - origin: 'subagent', - }, childEvents(descriptorPayload('lineage checked'))) - // The exact read reports a different durable parent than enumeration did. - mutateStoredHeader(ctx, childId, meta => ({ ...meta, parentSession: SessionId('someone-else') })) + const failure = new Error('backend listing failed') + vi.spyOn(ctx.sessionQuery, 'listSessions').mockRejectedValue(failure) + await expect(ctx.subagents.listDescendants(parent.id)).rejects.toBe(failure) + }) + + it('maps an aborted descendant corpus listing to the stable cancellation error', async () => { + const { ctx, parent } = await setup([]) + const controller = new AbortController() + vi.spyOn(ctx.sessionQuery, 'listSessions').mockImplementation(() => { + controller.abort() + return Promise.reject(new Error('backend listing aborted')) + }) + await expect(ctx.subagents.listDescendants(parent.id, controller.signal)).rejects.toMatchObject({ + code: 'CANCELLED', + }) + }) + + it('contains a live descendant projection failure and orders sibling ties by id', async () => { + const { ctx, parent } = await setup([]) + const laterId = SessionId('live-projection-z') + const earlierId = SessionId('live-projection-a') + for (const id of [laterId, earlierId]) { + const child = ctx.sessions.create(id, { + meta: { parentSession: parent.id, origin: 'subagent', createdAt: 5 }, + }) + child.append('subagent/descriptor', descriptorPayload(String(id))) + } + const snapshot = ctx.sessionProjections.snapshot.bind(ctx.sessionProjections) + vi.spyOn(ctx.sessionProjections, 'snapshot').mockImplementation((session, keys) => { + if (session.id === laterId) throw new Error('projection failed') + return snapshot(session, keys) + }) + await expect(ctx.subagents.listDescendants(parent.id)).resolves.toEqual([ - { kind: 'diagnostic', id: childId, reason: 'corrupt', parentId: parent.id, depth: 1 }, + { + kind: 'child', id: earlierId, label: String(earlierId), mode: 'continuable', + activity: 'running', hasChildren: false, parentId: parent.id, depth: 1, + }, + { kind: 'diagnostic', id: laterId, reason: 'corrupt', parentId: parent.id, depth: 1 }, ]) }) + it('serves a valid own-suffix descendant identity from the projection cache', async () => { + const { ctx, parent } = await setup([], { projectionCache: true }) + const childId = await authorChild(ctx, '00000000-0000-4000-8000-00000000ae01', { + parentSession: parent.id, + origin: 'subagent', + }, childEvents(descriptorPayload('disk label'))) + ctx.sessionProjectionCache.cachedSnapshot = () => ({ + asOfSeq: SessionSeq(2), + values: { subagent: { mode: 'one-shot', seq: SessionSeq(2) } }, + }) + const open = vi.spyOn(ctx.sessionPersistence, 'open') + + await expect(ctx.subagents.listDescendants(parent.id)).resolves.toEqual([{ + kind: 'child', id: childId, mode: 'one-shot', activity: 'inactive', hasChildren: false, + parentId: parent.id, depth: 1, + }]) + expect(open).not.toHaveBeenCalled() + }) + + it.each([ + ['absent', () => ({ asOfSeq: SessionSeq(0), values: {} })], + ['null', () => ({ asOfSeq: SessionSeq(0), values: { subagent: null } })], + ['inherited', () => ({ + asOfSeq: SessionSeq(1), + values: { subagent: { mode: 'continuable' as const, label: 'ancestor', seq: SessionSeq(1) } }, + })], + ])('falls back to the authoritative descendant fold for a %s cached identity', async (_name, cachedSnapshot) => { + const { ctx, parent } = await setup([], { projectionCache: true }) + const childId = await authorChild(ctx, `cached-fallback-${_name}`, { + parentSession: parent.id, + origin: 'subagent', + }, _name === 'inherited' + ? [ + { type: 'turn/start', seq: SessionSeq(0), time: 1, data: { turn: 1 } }, + { type: 'turn/end', seq: SessionSeq(1), time: 2, data: { turn: 1, reason: { kind: 'completed' } } }, + { type: 'subagent/descriptor', seq: SessionSeq(2), time: 3, data: descriptorPayload('own label') }, + ] as SessionEvent[] + : childEvents(descriptorPayload('own label')), + _name === 'inherited' ? 2 : undefined) + ctx.sessionProjectionCache.cachedSnapshot = cachedSnapshot + const open = vi.spyOn(ctx.sessionPersistence, 'open') + + await expect(ctx.subagents.listDescendants(parent.id, testSignal)).resolves.toEqual([{ + kind: 'child', id: childId, label: 'own label', mode: 'continuable', + activity: 'inactive', hasChildren: false, parentId: parent.id, depth: 1, + }]) + expect(open).toHaveBeenCalledTimes(1) + }) + + it('falls back to the authoritative descendant fold when a cache read throws', async () => { + const { ctx, parent } = await setup([], { projectionCache: true }) + const childId = await authorChild(ctx, 'cache-read-failure', { + parentSession: parent.id, + origin: 'subagent', + }, childEvents(descriptorPayload('recovered'))) + ctx.sessionProjectionCache.cachedSnapshot = () => { throw new Error('poisoned cache row') } + + await expect(ctx.subagents.listDescendants(parent.id)).resolves.toEqual([{ + kind: 'child', id: childId, label: 'recovered', mode: 'continuable', + activity: 'inactive', hasChildren: false, parentId: parent.id, depth: 1, + }]) + }) + + it.each([ + ['SESSION_QUERY_CORRUPT_SESSION', 'corrupt'], + ['SESSION_QUERY_SOURCE_CONFLICT', 'corrupt'], + ['OTHER', 'unavailable'], + ] as const)('maps a %s cold descendant read failure to %s', async (code, reason) => { + const { ctx, parent } = await setup([]) + const childId = await authorChild(ctx, `cold-failure-${code}`, { + parentSession: parent.id, + origin: 'subagent', + }, childEvents(descriptorPayload('unreadable'))) + const failure = Object.assign(new Error('cold read failed'), { code }) + vi.spyOn(ctx.sessionQuery, 'observeSession').mockRejectedValue(failure) + + await expect(ctx.subagents.listDescendants(parent.id)).resolves.toEqual([{ + kind: 'diagnostic', id: childId, reason, parentId: parent.id, depth: 1, + }]) + }) + + it('maps a non-Error cold descendant rejection to unavailable', async () => { + const { ctx, parent } = await setup([]) + const childId = await authorChild(ctx, 'cold-non-error-failure', { + parentSession: parent.id, + origin: 'subagent', + }, childEvents(descriptorPayload('unreadable'))) + vi.spyOn(ctx.sessionQuery, 'observeSession').mockImplementation(() => + // A backend can violate the Error rejection convention at this durable boundary. + // oxlint-disable-next-line typescript/prefer-promise-reject-errors -- exercises that non-Error boundary + Promise.reject('cold read failed')) + + await expect(ctx.subagents.listDescendants(parent.id)).resolves.toEqual([{ + kind: 'diagnostic', id: childId, reason: 'unavailable', parentId: parent.id, depth: 1, + }]) + }) + + it('maps a cold descendant failure racing cancellation to cancellation', async () => { + const { ctx, parent } = await setup([]) + await authorChild(ctx, 'cold-cancelled-failure', { + parentSession: parent.id, + origin: 'subagent', + }, childEvents(descriptorPayload('cancelled'))) + const controller = new AbortController() + vi.spyOn(ctx.sessionQuery, 'observeSession').mockImplementation(() => { + controller.abort() + return Promise.reject(new Error('cold read failed')) + }) + + await expect(ctx.subagents.listDescendants(parent.id, controller.signal)).rejects.toMatchObject({ + code: 'CANCELLED', + }) + }) + + it('maps cancellation after a successful cold descendant read to cancellation', async () => { + const { ctx, parent } = await setup([]) + await authorChild(ctx, 'cold-cancelled-success', { + parentSession: parent.id, + origin: 'subagent', + }, childEvents(descriptorPayload('cancelled'))) + const controller = new AbortController() + const observe = ctx.sessionQuery.observeSession.bind(ctx.sessionQuery) + vi.spyOn(ctx.sessionQuery, 'observeSession').mockImplementation(async (id, options) => { + const observation = await observe(id, options) + controller.abort() + return observation + }) + + await expect(ctx.subagents.listDescendants(parent.id, controller.signal)).rejects.toMatchObject({ + code: 'CANCELLED', + }) + }) + it('a pre-aborted signal stops the descendant scan before persistence reads', async () => { const { ctx, parent } = await setup([textResponse('done')]) await startChild(ctx, parent, 'never read') @@ -1355,9 +766,25 @@ describe('SubagentRuntime.listDescendants', () => { }) it('fails loud when the projection registry is not mounted', async () => { - const ctx = await setupWithoutProjections() + const ctx = new Context() + await ctx.plugin(SessionStore) + await ctx.plugin(SubagentRuntime) await expect(ctx.subagents.listDescendants(SessionId('no-projections-root'))).rejects.toThrow( expect.objectContaining({ code: 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE' }) as Error, ) }) + it('verifies a cold candidate still belongs to its enumerated lifecycle', async () => { + const { ctx, parent } = await setup([]) + const childId = await authorChild(ctx, '00000000-0000-4000-8000-00000000ddd1', { + parentSession: parent.id, + createdAt: 1, + origin: 'subagent', + }, childEvents(descriptorPayload('lineage checked'))) + // The exact read reports a different durable parent than enumeration did. + mutateStoredHeader(ctx, childId, meta => ({ ...meta, parentSession: SessionId('someone-else') })) + await expect(ctx.subagents.listDescendants(parent.id)).resolves.toEqual([ + { kind: 'diagnostic', id: childId, reason: 'corrupt', parentId: parent.id, depth: 1 }, + ]) + }) + }) diff --git a/packages/subagent/subagent/tests/service.spec.ts b/packages/subagent/subagent/tests/service.spec.ts index f40fc11dff..01a17cb591 100644 --- a/packages/subagent/subagent/tests/service.spec.ts +++ b/packages/subagent/subagent/tests/service.spec.ts @@ -276,7 +276,7 @@ describe('SubagentRuntime', () => { const parentSession = Session.create(SessionId('catalog-parent')) const childSession = Session.create(SessionId('catalog-child')) const parent = { id: parentSession.id, session: parentSession } as Agent - const localAgent = { id: childSession.id, session: childSession } as Agent + const localAgent = { id: childSession.id, session: childSession, options: {} } as Agent const result = Promise.withResolvers() const cleanupFailure = new Error('dispose also failed') const warnings = vi.spyOn(ctx.logger, 'warn') diff --git a/packages/subagent/tool-subagent-control/README.i18n.yaml b/packages/subagent/tool-subagent-control/README.i18n.yaml index 177ebd1d61..b8478ed970 100644 --- a/packages/subagent/tool-subagent-control/README.i18n.yaml +++ b/packages/subagent/tool-subagent-control/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/tool-subagent-control/README.md -README.md: afc084c442a78b368e0698630828b0e0261da553 -README.zh.md: 044902d7056ee4ed899c1f860db14898023fd907 +README.md: 2cfa000f1ba9f7950b28369a9b7bd3523610b579 +README.zh.md: f2154fde965899e7b4f30271846bce52414b010d diff --git a/packages/subagent/tool-subagent-control/README.md b/packages/subagent/tool-subagent-control/README.md index afc084c442..2cfa000f1b 100644 --- a/packages/subagent/tool-subagent-control/README.md +++ b/packages/subagent/tool-subagent-control/README.md @@ -54,7 +54,7 @@ Stops only the target's current turn: queued messages stay parked until a later ### list_agents -Lists the continuable children below the calling agent: `children` (default) shows direct children, `descendants` walks the whole tree in stable pre-order, annotating each entry with its durable direct-parent session id and depth. Status comes from the live Agent registry — `running` or `inactive`. One-shot children are intentionally absent because they cannot accept `send_message`, and unreadable candidates appear as diagnostics. +Lists the continuable children below the calling agent: `children` (default) reads direct children from the parent catalog without opening child logs; `descendants` walks the whole tree in stable pre-order, annotating each entry with its durable direct-parent session id and depth. Status comes from the live Agent registry — `running` or `inactive`. One-shot children are intentionally absent because they cannot accept `send_message`, and unreadable candidates appear as diagnostics only in `descendants` scope. ----- @@ -150,7 +150,7 @@ Append-only; newly visible content follows the reusable request prefix and does #### What the model sees -One line per continuable child in stable catalog order: ` [] —