Merge master into feat/subagent-catalog-names

This commit is contained in:
Dudu-0223
2026-11-04 14:16:00 +08:00
65 changed files with 1675 additions and 274 deletions
@@ -0,0 +1,22 @@
# Bilingual-pair consistency record for 2026-10-26-manual-generation-continuation.md (docs/i18n/README.md): per heading
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
# After editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-10-26-manual-generation-continuation.md
/agent-note-manual-generation-continuation:
en: 327aaa1cdc63b1f5
zh: 1147b4a23e51772c
/agent-note-manual-generation-continuation/problem:
en: f118844946afdbdc
zh: f1fe37d042f88b24
/agent-note-manual-generation-continuation/decision:
en: 463db7deb7710e07
zh: cfacb69cb58349a9
/agent-note-manual-generation-continuation/alternatives-considered:
en: 58bb948d210d42ea
zh: 5dc920d222d71218
/agent-note-manual-generation-continuation/consequences:
en: e86aee3a7da7649f
zh: d58e8cc94e5008bf
/agent-note-manual-generation-continuation/verification:
en: e31a5bd5826c689f
zh: 02ac700146246664
@@ -0,0 +1,33 @@
# Agent Note: Manual generation continuation
Status: implemented
English | [中文](2026-10-26-manual-generation-continuation.zh.md)
## Problem
Users need another request after a model failure without inserting an artificial instruction. Browser paging can omit the failed turn's start, and streaming must not repeatedly copy history.
## Decision
The play action submits `content: []` through the existing Session prompt API. The API assigns `source.kind: 'retry'`; unchanged AgentLoop admission records an empty `user/message` and opens a normally balanced new turn. Chat presents a compact continuation-request receipt while the log retains the empty input. The original failed turn remains closed.
The Session API owns the fixed-size `conversationContinuation` projection and shares its value with the browser. Admission requires an eligible failure, true idle ownership, and no pending human input. An appended empty retry message admits the new turn, preserving eligibility if its request also fails.
The six-code manual allowlist stays independent of provider retry policy. Non-waking injected context accompanies the request. The accepted user message retains request-id deduplication after the inbox input is claimed. Reusing ordinary message admission avoids a Loop branch and a separate durable acceptance event.
## Alternatives considered
**Localized or hidden continuation text.** Adds model-visible instructions and changes retained history.
**A separate resume operation.** The existing prompt and inbox already carry identified control input and own wakeup.
**Keep the failed turn waiting for a click.** Changes failure settlement, idle status, cancellation, and model-selection semantics.
## Consequences
Ordinary empty-draft Enter remains inert. The explicit action reuses submission state and error reporting without an echo or generated draft. Pre-step rejection and cleared batches still prevent model calls.
## Verification
Unit and assembled scenarios cover repeated failure, request deduplication, injected context, balanced turns, retained tools, one original user message, and zero Client event-window reads.
@@ -0,0 +1,33 @@
# Agent Note: 手动继续生成
Status: implemented
[English](2026-10-26-manual-generation-continuation.md) | 中文
## 问题
模型请求失败后,用户需要再次请求,但不应插入人为构造的指令。浏览器分页可能缺少失败轮次起点,流式输出也不能反复复制历史。
## 决策
播放按钮通过现有 Session prompt API 提交 `content: []`。API 指定 `source.kind: 'retry'`;AgentLoop 沿用普通准入,记录空 `user/message` 并开启正常闭合的新轮次。Chat 显示轻量的继续请求记录,日志保留空输入。原失败轮次保持闭合。
Session API 拥有固定大小的 `conversationContinuation` 投影,向浏览器发布相同的值。准入要求失败符合条件、持有真正的空闲状态且没有待消费的用户输入。追加的空重试消息使新轮次获得准入,因此请求再次失败后仍保留继续资格。
六码手动白名单独立于提供方重试策略。非唤醒的注入上下文随请求进入。inbox 输入被领取后,已接受的用户消息仍支持 request-id 去重。复用普通消息准入避免增加 Loop 分支及独立持久接受事件。
## 考虑过的替代方案
**本地化或隐藏的继续文本。** 增加模型可见指令并改变保留历史。
**单独的 resume 操作。** 现有 prompt 和 inbox 已可承载带身份的控制输入并拥有唤醒流程。
**保持失败轮次等待点击。** 改变失败结算、空闲状态、取消和模型选择语义。
## 后果
普通空草稿回车仍不执行。显式继续沿用提交状态与错误报告,不创建消息回显或生成草稿。pre-step 拒绝和被清空的批次仍阻止模型调用。
## 验证
单元和组装场景覆盖重复失败、请求去重、注入上下文、轮次闭合、工具结果保留、仅一条原始用户消息,以及客户端不读取完整事件窗口。
+48 -4
View File
@@ -27,7 +27,7 @@ import {
compareOrRefreshGolden, fixtureUserPrompts,
launchWebScaffold, recordFixture, watchConsole, webSnapshotMode, type WebScaffold,
} from './scaffold.ts'
import { connectFreshWorkspace, newEnglishPage, saveFailureShot } from './support.ts'
import { connectFreshWorkspace, newEnglishPage, saveFailureShot, writeComposerDraft } from './support.ts'
const SNAPSHOT_DIR = fileURLToPath(new URL('../../../snapshots/web/live-interactions', import.meta.url))
const FIXTURE = join(SNAPSHOT_DIR, 'session.v3.jsonl')
@@ -414,15 +414,16 @@ describe('web e2e: live-turn interactions (cancel / error / retry)', () => {
expect(tripwire.warnings).toEqual([])
}, 120_000)
it.skipIf(MODE === 'record')('surfaces the terminal turn error after transient retries exhaust', async () => {
it.skipIf(MODE === 'record')('continues after transient retries exhaust without another user bubble', async () => {
// A whole-script replacement: three throw entries cover the first request
// plus both budgeted retries (patches cannot reach past the one-call
// derived script). The scenario-owned policy keeps exhaustion fast and
// jitter-free instead of walking the shared default's five backed-off
// attempts.
const failure: ReplayEntry = { kind: 'throw', chunks: [], message: 'upstream 503', code: 'SERVER' }
const derived = deriveReplayScript(parseSessionLog(await readFile(FIXTURE, 'utf8')))
await launch(
() => [failure, failure, failure],
() => [failure, failure, failure, ...derived],
{ mode: 'normal', maxRetries: 2, retryableCodes: ['SERVER'], backoff: { initialDelayMs: 25, maxDelayMs: 50, jitterRatio: 0 } },
)
onTestFailed(() => saveFailureShot(page, 'web-e2e-retry-exhausted'))
@@ -443,6 +444,49 @@ describe('web e2e: live-turn interactions (cancel / error / retry)', () => {
// context; the golden pins both.
const snapshot = await captureStableAria(page, '[class*="centerCol"]', scaffold!.workspaceCwd)
await compareOrRefreshGolden(RETRY_EXHAUSTED_EXPECTED, snapshot, MODE)
await page.reload({ waitUntil: 'load' })
const resume = page.getByRole('button', { name: 'Continue generating', exact: true })
await resume.waitFor()
const input = page.locator('[data-composer-input]').first()
await writeComposerDraft(page, input, '/plan ')
await input.press('Enter')
const plan = page.getByRole('button', { name: 'Plan mode on, press to turn off', exact: true })
await plan.waitFor()
await expect.poll(() => input.textContent()).toBe('')
await plan.click()
await plan.waitFor({ state: 'hidden' })
await resume.waitFor()
expect(await resume.isEnabled()).toBe(true)
expect(turnEndReasons(sessionEvents)).toEqual(['error'])
await writeComposerDraft(page, input, 'A different instruction')
expect(await resume.count()).toBe(0)
expect(await page.getByRole('button', { name: 'Send message', exact: true }).isEnabled()).toBe(true)
await writeComposerDraft(page, input, '')
await resume.waitFor()
await page.setViewportSize({ width: 390, height: 844 })
// ResizeObserver collapses the model label after the viewport changes.
await expect.poll(async () => {
const bounds = await resume.boundingBox()
return bounds !== null && bounds.x + bounds.width <= 390
}).toBe(true)
expect(await resume.isEnabled()).toBe(true)
const continued = scaffold!.whenTurnSettled()
await resume.click()
await continued
expect(turnEndReasons(sessionEvents)).toEqual(['error', 'completed'])
expect(sessionEvents.some(event => event.type === 'user/message' && event.data.source.kind === 'plan-mode')).toBe(true)
const userMessages = sessionEvents.flatMap(event => event.type === 'user/message' && event.data.source.kind === 'user'
? [event.data] : [])
expect(userMessages.map(message => message.content)).toEqual([[{ type: 'text', text: PROMPT }]])
const retries = sessionEvents.filter(event => event.type === 'user/message' && event.data.source.kind === 'retry')
expect(retries).toHaveLength(1)
expect(retries[0]?.data).toMatchObject({ content: [], source: { kind: 'retry' } })
expect(sessionEvents.filter(event => event.type === 'turn/start')).toHaveLength(2)
expect(sessionEvents.filter(event => event.type === 'turn/end')).toHaveLength(2)
expect(await resume.count()).toBe(0)
await page.setViewportSize({ width: 1440, height: 900 })
await compareOrRefreshGolden(join(SNAPSHOT_DIR, 'continued.expected.md'),
await captureStableAria(page, '[class*="centerCol"]', scaffold!.workspaceCwd), MODE)
expect(tripwire.pageErrors).toEqual([])
expect(tripwire.warnings).toEqual([])
}, 120_000)
@@ -451,7 +495,7 @@ describe('web e2e: live-turn interactions (cancel / error / retry)', () => {
await assertFixtureInventory(SNAPSHOT_DIR, [
'session.v3.jsonl', 'cancel.expected.md', 'cancel-expanded.expected.md',
'loading.expected.md', 'running-draft.expected.md', 'error-auth.expected.md',
'retry.expected.md', 'retry-expanded.expected.md', 'retry-request.expected.md', 'retry-exhausted.expected.md',
'retry.expected.md', 'retry-expanded.expected.md', 'retry-request.expected.md', 'retry-exhausted.expected.md', 'continued.expected.md',
])
})
})
+5 -5
View File
@@ -23,11 +23,11 @@ Application listeners are outside this package matrix. Desktop Host subscribes t
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:389`](../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:309`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), `server`, `session-controller` |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:417`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) |
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:701`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:681`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:708`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:687`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:694`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:705`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:685`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:712`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:691`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:698`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `app-boot/config-reload` | `emit` | [`packages/boot/app-boot/src/index.ts:55`](../packages/boot/app-boot/src/index.ts) | [`app-boot`](../packages/boot/app-boot) (`emit`) | [`settings`](../packages/settings/settings) |
| `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:87`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes`, `server` |
| `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | - |
+5 -5
View File
@@ -25,11 +25,11 @@
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:389`](../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:309`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), `server`, `session-controller` |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:417`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) |
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:701`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:681`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:708`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:687`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:694`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:705`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:685`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:712`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:691`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:698`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `app-boot/config-reload` | `emit` | [`packages/boot/app-boot/src/index.ts:55`](../packages/boot/app-boot/src/index.ts) | [`app-boot`](../packages/boot/app-boot) (`emit`) | [`settings`](../packages/settings/settings) |
| `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:87`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes`, `server` |
| `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | - |
+64 -58
View File
@@ -9,8 +9,8 @@
en: 1387c4505dde2faf
zh: 48570fa1c13d6910
/session-persistence-event-catalog/persistence-type-fingerprints:
en: fed3fbb5fe6daaa5
zh: 33602df315412372
en: 35ffb6107a5fbae2
zh: 06ce2128075e157b
/session-persistence-event-catalog/event-envelope:
en: 56414ffd00cdc32a
zh: 6dc11eb013e95e41
@@ -717,8 +717,11 @@
en: ade80ed58d3b63b2
zh: ade80ed58d3b63b2
/session-persistence-event-catalog/resolved-persistence-types/resume:
en: e27772872766bd6d
zh: e27772872766bd6d
en: f9a34b26963fc22d
zh: f9a34b26963fc22d
/session-persistence-event-catalog/resolved-persistence-types/retry:
en: 68c90ebe83c80004
zh: 68c90ebe83c80004
/session-persistence-event-catalog/resolved-persistence-types/runtime-context:
en: 784f0d4afdaaa472
zh: 784f0d4afdaaa472
@@ -1023,11 +1026,11 @@
en: a6a2e38fdd6d127a
zh: 1fe82356d89f5769
/session-persistence-event-catalog/resolved-persistence-types/deepseeksearchllmrequest:
en: 054dbd6367e1403d
zh: 5b071d10ae1ec245
en: 8cc704c4048167a7
zh: d27823620065ad25
/session-persistence-event-catalog/resolved-persistence-types/developermessage:
en: 58bc64eb0f7fb589
zh: 8cc8279eb5786ef5
en: b91fd6f924b6d84e
zh: c74abb179c889ed6
/session-persistence-event-catalog/resolved-persistence-types/epochheader:
en: 3bdc8ecd0bdf0c9c
zh: 0fe5b75c174ebab4
@@ -1137,11 +1140,11 @@
en: 6dbe099c62f7c226
zh: 6fd788f63c038c91
/session-persistence-event-catalog/resolved-persistence-types/llmretrystartedeventdata:
en: a3754a186db0e1bb
zh: e9467b50a27889d5
en: fdd00b0eb42e499d
zh: a6dc05d9a0a8f39e
/session-persistence-event-catalog/resolved-persistence-types/message:
en: 0be581a4095c3493
zh: 2c815426f3d3717a
en: 0a728ea7fb7a297e
zh: 9539ccd702170fa6
/session-persistence-event-catalog/resolved-persistence-types/messagefeedbackdelete:
en: c582953270d4ca44
zh: 966ccfe2e7660a2a
@@ -1152,14 +1155,14 @@
en: f58575a1fc96df42
zh: 9f0c6ed9033e5c9d
/session-persistence-event-catalog/resolved-persistence-types/messagefeedbackrating:
en: 702995c31653ab91
zh: cf60875749663bd3
en: 1918aad92fd51fc9
zh: c36696f1b77baa7d
/session-persistence-event-catalog/resolved-persistence-types/messagesource:
en: 1ec5fd7b1b8050a9
zh: ee4a3f61be48cd17
en: 80d51b79557bc4d8
zh: e7a9721b8b3ea9f3
/session-persistence-event-catalog/resolved-persistence-types/message~2:
en: 9e25f2f1513f7b15
zh: 2723b6aa3d8b723e
en: 7106ebd39f6cd290
zh: 4e36b5377d222a0a
/session-persistence-event-catalog/resolved-persistence-types/modelmessagesource:
en: 5f9154ca34235ab9
zh: a833105910ebfa82
@@ -1218,11 +1221,11 @@
en: 9a54c4478ad3b620
zh: 02c4c1fd7e252770
/session-persistence-event-catalog/resolved-persistence-types/sessiontitleeventdata:
en: a537c3568f3f07db
zh: 20c97f3c3fd82e8b
en: 2cf3dc8a82d4d4be
zh: 638e945c5007d6f4
/session-persistence-event-catalog/resolved-persistence-types/sessiontitlellmrequesteventdata:
en: efa083dfdcf04208
zh: eed525395ff9f2e8
en: b45c7e8370d7be1e
zh: 252fdc0ff2b9338c
/session-persistence-event-catalog/resolved-persistence-types/sessiontitlemodelidentity:
en: 9531468264499498
zh: 9da23c0ad2776563
@@ -1332,14 +1335,14 @@
en: 778debd61e0284a2
zh: 2cc82ad9e80f18b1
/session-persistence-event-catalog/resolved-persistence-types/turnendreason:
en: bcd450bc3ade2a1a
zh: e442be61e4391383
en: 50736659a0e79990
zh: 34ebfd42a70069e3
/session-persistence-event-catalog/resolved-persistence-types/usermessage:
en: 6f29a4e108379f9a
zh: 2bf0f494b8fcd2b2
en: 92cc51a395ca7c7b
zh: 4bd6029ea1241e25
/session-persistence-event-catalog/resolved-persistence-types/usermessage~2:
en: e4fc10ce549b51ad
zh: cb29ffcb8003b355
en: f36c65420460fcf1
zh: 4208e6734c0672df
/session-persistence-event-catalog/resolved-persistence-types/workflowagentoutcome:
en: d0a3f9aab18c3de5
zh: 76ac69a835ca4e29
@@ -1365,8 +1368,8 @@
en: 4147b170f52814af
zh: e78991ac1c41ebec
/session-persistence-event-catalog/resolved-persistence-types/string:
en: caa52cd38cec3aee
zh: 3ff0f1fceaac2eb1
en: ef89e74973f4a575
zh: 0bb1564a0418501c
/session-persistence-event-catalog/resolved-persistence-types/string~2:
en: 0089620bf4638263
zh: 1922bef1713094bb
@@ -1536,11 +1539,11 @@
en: 4cb1c48095df98dc
zh: 5a03e44761af559e
/session-persistence-event-catalog/resolved-persistence-types/header-reason-startsseries:
en: c21561adcf9398a5
zh: fac8b21392750aae
en: 20d5dc748cb93377
zh: ede516e3b59313a7
/session-persistence-event-catalog/resolved-persistence-types/headerseq-message-step-turn:
en: 081d257a87d8fb2d
zh: 49bdba3da8d5f7e4
en: c4ea1e643651b5c1
zh: 8f985997e5a942ec
/session-persistence-event-catalog/resolved-persistence-types/height-width:
en: a5df50710083ac25
zh: aad3ccf6f6de70e4
@@ -1557,11 +1560,11 @@
en: 41f73c58a77dfa28
zh: af77f4aee3cb4a40
/session-persistence-event-catalog/resolved-persistence-types/inherited:
en: 7c2c00c4635970ca
zh: 19818a2c43b4c57d
en: 55a056f4b970329f
zh: 6763a01bb6abe753
/session-persistence-event-catalog/resolved-persistence-types/inserted-outcome-removedcount-start:
en: 67b7eda689a3a115
zh: 5ffdf39f3ee061b2
en: d2b118f32769b0d9
zh: edea493977131d2b
/session-persistence-event-catalog/resolved-persistence-types/interrupted-message-step-stream:
en: 8e86cd838e3e4a49
zh: f5fec2a8adf1f3cc
@@ -1755,8 +1758,11 @@
en: 1f6dbdbf5d923df0
zh: aea576e5ec34c0fc
/session-persistence-event-catalog/resolved-persistence-types/kind-repeat-tool-reminder-form-snapshot:
en: e9c88cceef2d8432
zh: 14fb0897543b6960
en: f58bccca3df9c2ad
zh: 5c92b6edeb7ce020
/session-persistence-event-catalog/resolved-persistence-types/kind-retry:
en: c628d0575f81407a
zh: d9a70ce1e05dcce8
/session-persistence-event-catalog/resolved-persistence-types/kind-runtime-context:
en: 68b5598e21cf8ba2
zh: 95ef1685af64a5f4
@@ -1893,8 +1899,8 @@
en: 4e102391d685eff5
zh: 9762243a13014f3d
/session-persistence-event-catalog/resolved-persistence-types/kind-user:
en: eaecebdbcd5cc4e4
zh: f519d7ade666f48a
en: 808d28208287e843
zh: 18a8d63978c984a7
/session-persistence-event-catalog/resolved-persistence-types/kind-user-approval:
en: a52d2dfbaf844127
zh: 4c5306ca40f20873
@@ -1980,11 +1986,11 @@
en: 374b8adee8d571fa
zh: b21057efc58e6490
/session-persistence-event-catalog/resolved-persistence-types/type-agent-preset-selected:
en: 2ce26699bb57cf69
zh: a5fc9ea510a3d458
en: b85970209e42ae80
zh: 83041799d5da5d74
/session-persistence-event-catalog/resolved-persistence-types/type-agent-inbox-spliced:
en: ae0b65d2268c758b
zh: 8244a6d65cfb01f3
en: 1c6e8cf2fa5408c4
zh: 14d24d858024e8cf
/session-persistence-event-catalog/resolved-persistence-types/type-approval-asked:
en: 9c77f18b0dad22f0
zh: 8894cf2878fe90db
@@ -2028,11 +2034,11 @@
en: ba73fb10b7e2ffc9
zh: 8d5c97e63e5f16da
/session-persistence-event-catalog/resolved-persistence-types/type-deliverables-presented:
en: f5c7b6c1d3610861
zh: 2baec8a404127ce8
en: 4b644c52aeab2ca7
zh: 9f28958d7882f403
/session-persistence-event-catalog/resolved-persistence-types/type-developer-message:
en: fe3390ea4e6769e3
zh: 5a25cbdf990ef85f
en: 6b632a8f70a45496
zh: ad6c793e41731fd7
/session-persistence-event-catalog/resolved-persistence-types/type-disabled:
en: 585627a50ece4e5f
zh: 157837aee3da0ac3
@@ -2106,11 +2112,11 @@
en: acf7e21e4d21ebff
zh: fb83a853634d204a
/session-persistence-event-catalog/resolved-persistence-types/type-session-title:
en: d26d1cd97d87f4a6
zh: 992f1290578da1f4
en: 65cf6985bf6b1e6d
zh: 9a18aff2bea3b213
/session-persistence-event-catalog/resolved-persistence-types/type-session-title-llm-request:
en: 211b5793ff00bed6
zh: e8382b4f9adb08fd
en: 3c14dc1ac427e847
zh: b0cacc9b61b1209b
/session-persistence-event-catalog/resolved-persistence-types/type-step-end:
en: 7fc233c4a569dae2
zh: bc2b3fed4a397c00
@@ -2190,11 +2196,11 @@
en: 1b045de96172be4b
zh: 8a15c6f35b576b37
/session-persistence-event-catalog/resolved-persistence-types/type-usage:
en: 1f43a7944fa86bcf
zh: faa883c372923440
en: 5c4bf682faecace1
zh: e2014c3dc10bae79
/session-persistence-event-catalog/resolved-persistence-types/type-user-message:
en: 28e1108b02b392dc
zh: 0dde507cef7d790e
en: fd9f5dacef8c0ce8
zh: 79eab747b55dfaac
/session-persistence-event-catalog/resolved-persistence-types/type-web-deepseek-search-llm-request:
en: 99c8837344178a47
zh: bf746f5678346596
+69 -45
View File
@@ -23,7 +23,7 @@ The [format references](persistence-changes/historical-formats/README.md) cover
| `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 | `ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482` | [`{ type: "agent/inbox/spliced" }`](#persistence-type-sha256-ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482) |
| `event:agent/inbox/spliced` | event | `1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85` | [`{ type: "agent/inbox/spliced" }`](#persistence-type-sha256-1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85) |
| `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) |
@@ -36,7 +36,7 @@ The [format references](persistence-changes/historical-formats/README.md) cover
| `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 | `70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a` | [`{ type: "developer/message" }`](#persistence-type-sha256-70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a) |
| `event:developer/message` | event | `510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99` | [`{ type: "developer/message" }`](#persistence-type-sha256-510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99) |
| `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) |
@@ -58,7 +58,7 @@ The [format references](persistence-changes/historical-formats/README.md) cover
| `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 | `d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca` | [`{ type: "session/title-llm-request" }`](#persistence-type-sha256-d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca) |
| `event:session/title-llm-request` | event | `3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18` | [`{ type: "session/title-llm-request" }`](#persistence-type-sha256-3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18) |
| `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 | `d49164d37eab0f0f70fa787c65d887abbea869c010ccb103d717fab3519c3a41` | [`{ type: "subagent/catalog" }`](#persistence-type-sha256-d49164d37eab0f0f70fa787c65d887abbea869c010ccb103d717fab3519c3a41) |
@@ -81,7 +81,7 @@ The [format references](persistence-changes/historical-formats/README.md) cover
| `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 | `dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450` | [`{ type: "user/message" }`](#persistence-type-sha256-dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450) |
| `event:user/message` | event | `50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97` | [`{ type: "user/message" }`](#persistence-type-sha256-50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97) |
| `event:web/deepseek-search-llm-request` | event | `0c556c9b9f2a96238a6b9bbb99e748206cbff2ed6203041c9571f04ae5802f52` | [`{ type: "web/deepseek-search-llm-request" }`](#persistence-type-sha256-0c556c9b9f2a96238a6b9bbb99e748206cbff2ed6203041c9571f04ae5802f52) |
| `event:working-directory/change` | event | `124aa62078ca3311353b39cc3bf6c75da281338be6bbf672f8b361d828cddca3` | [`{ type: "working-directory/change" }`](#persistence-type-sha256-124aa62078ca3311353b39cc3bf6c75da281338be6bbf672f8b361d828cddca3) |
| `event:workspace/changes` | event | `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | [`{ type: "workspace/changes" }`](#persistence-type-sha256-e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72) |
@@ -2446,6 +2446,14 @@ SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66`
`"resume"`
<a id="persistence-type-sha256-63ba8895cc09e4693cf0819fdcd18c084bef195febda5b6a23af279b3852be36"></a>
### `"retry"`
SHA-256: `63ba8895cc09e4693cf0819fdcd18c084bef195febda5b6a23af279b3852be36`
`"retry"`
<a id="persistence-type-sha256-24b10f7cdae64928f89c49afc2eca0af9eb4a2f135e16f3416e6b8461fef1748"></a>
### `"runtime-context"`
@@ -3418,7 +3426,7 @@ Sources: [`packages/web/web-search-deepseek/src/provider.ts:55`](../packages/web
| `body` | required | [`{ max_tokens, messages, model, thinking?, … }`](#persistence-type-sha256-9c001ecb5e1d3c3894410db2a1e383842e5f8454fb52182338686158abc1b3ee) |
| `endpoint` | required | `string` |
<a id="persistence-type-sha256-01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796"></a>
<a id="persistence-type-sha256-824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc"></a>
<a id="persistence-type-developermessage"></a>
@@ -3426,7 +3434,7 @@ Sources: [`packages/web/web-search-deepseek/src/provider.ts:55`](../packages/web
### `DeveloperMessage`
SHA-256: `01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796`
SHA-256: `824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc`
Sources: [`packages/llm/llm/src/message.ts:157`](../packages/llm/llm/src/message.ts)
@@ -3435,7 +3443,7 @@ Sources: [`packages/llm/llm/src/message.ts:157`](../packages/llm/llm/src/message
| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) |
| `id` | required | `string` |
| `role` | required | `"developer"` |
| `source` | required | [`MessageSource`](#persistence-type-sha256-b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72) |
| `source` | required | [`MessageSource`](#persistence-type-sha256-dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce) |
Source compatibility: `source` — `session-source-attribution` v1; `session.developer-message.source`; `kind`; `preserve`.
@@ -4134,7 +4142,7 @@ Sources: [`packages/llm/llm-retry/src/types.ts:43`](../packages/llm/llm-retry/sr
| `step` | required | `number` |
| `turn` | required | `number` |
<a id="persistence-type-sha256-e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39"></a>
<a id="persistence-type-sha256-c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8"></a>
<a id="persistence-type-message"></a>
@@ -4142,15 +4150,15 @@ Sources: [`packages/llm/llm-retry/src/types.ts:43`](../packages/llm/llm-retry/sr
### `Message`
SHA-256: `e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39`
SHA-256: `c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8`
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-01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796)
- [`UserMessage`](#persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1)
- [`DeveloperMessage`](#persistence-type-sha256-824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc)
- [`UserMessage`](#persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c)
- [`SystemMessage`](#persistence-type-sha256-09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363)
- [`AssistantMessage`](#persistence-type-sha256-fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be)
@@ -4227,7 +4235,7 @@ One of:
- `"negative"`
- `"positive"`
<a id="persistence-type-sha256-b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72"></a>
<a id="persistence-type-sha256-dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce"></a>
<a id="persistence-type-messagesource"></a>
@@ -4235,7 +4243,7 @@ One of:
### `MessageSource`
SHA-256: `b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72`
SHA-256: `dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce`
Sources: [`packages/llm/llm/src/message.ts:136`](../packages/llm/llm/src/message.ts)
@@ -4297,6 +4305,7 @@ Sources: [`packages/llm/llm/src/message.ts:136`](../packages/llm/llm/src/message
| `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) |
| `retry` | not declared | `rpcId`: `string` | [`{ kind: "retry" }`](#persistence-type-sha256-8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e) |
| `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) |
@@ -4360,13 +4369,13 @@ Sources: [`packages/llm/llm/src/message.ts:136`](../packages/llm/llm/src/message
| `webhook` | `"notice"` | `deliveryId`: `string`; `provider`: `string`; `ruleId`: `string`; `source`: `string`; `summary`: `string` | [`{ kind: "webhook", form: "notice" }`](#persistence-type-sha256-9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94) |
| `working-directory` | not declared | none | [`{ kind: "working-directory" }`](#persistence-type-sha256-2235d957bf4b7c6cf959231d480f0ba1f3a6d72d82981493fb6c7c963021d3d5) |
<a id="persistence-type-sha256-95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70"></a>
<a id="persistence-type-sha256-42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0"></a>
### `Message[]`
SHA-256: `95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70`
SHA-256: `42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0`
Array of [`Message`](#persistence-type-sha256-e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39).
Array of [`Message`](#persistence-type-sha256-c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8).
<a id="persistence-type-sha256-719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91"></a>
@@ -4734,7 +4743,7 @@ Sources: [`packages/session/session-title/src/types.ts:41`](../packages/session/
| `source` | required | [`SessionTitleSource`](#persistence-type-sha256-30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f) |
| `title` | required | `string` |
<a id="persistence-type-sha256-601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25"></a>
<a id="persistence-type-sha256-bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4"></a>
<a id="persistence-type-packagessessionsession-title-llmsrcindextssessiontitlellmrequesteventdata"></a>
@@ -4742,7 +4751,7 @@ Sources: [`packages/session/session-title/src/types.ts:41`](../packages/session/
### `SessionTitleLlmRequestEventData`
SHA-256: `601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25`
SHA-256: `bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4`
Sources: [`packages/session/session-title-llm/src/index.ts:43`](../packages/session/session-title-llm/src/index.ts)
@@ -4750,7 +4759,7 @@ Sources: [`packages/session/session-title-llm/src/index.ts:43`](../packages/sess
|---|---|---|
| `maxTokens` | required | `number` |
| `messageSeqs` | required | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) |
| `messages` | required | [`Message[]`](#persistence-type-sha256-95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70) |
| `messages` | required | [`Message[]`](#persistence-type-sha256-42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0) |
| `reasoningEffort` | optional | `string` |
| `route` | required | [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) |
| `system` | required | `string` |
@@ -5429,7 +5438,7 @@ Sources: [`packages/core/session/src/types.ts:238`](../packages/core/session/src
| `interrupted` | not declared | none | [`{ kind: "interrupted" }`](#persistence-type-sha256-56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23) |
| `max-tokens` | not declared | none | [`{ kind: "max-tokens" }`](#persistence-type-sha256-ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7) |
<a id="persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1"></a>
<a id="persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c"></a>
<a id="persistence-type-packagesllmllmsrcmessagetsusermessage"></a>
@@ -5437,7 +5446,7 @@ Sources: [`packages/core/session/src/types.ts:238`](../packages/core/session/src
### `UserMessage`
SHA-256: `613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1`
SHA-256: `74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c`
Sources: [`packages/llm/llm/src/message.ts:162`](../packages/llm/llm/src/message.ts)
@@ -5446,19 +5455,19 @@ Sources: [`packages/llm/llm/src/message.ts:162`](../packages/llm/llm/src/message
| `content` | required | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) |
| `id` | required | `string` |
| `role` | required | `"user"` |
| `source` | required | [`MessageSource`](#persistence-type-sha256-b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72) |
| `source` | required | [`MessageSource`](#persistence-type-sha256-dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce) |
Source compatibility: `source` — `session-source-attribution` v1; `session.user-message.source`; `kind`; `preserve`.
Attribution-only additions: `action-cards`, `tmux-context`, `user-question-reply`, `working-directory`.
<a id="persistence-type-sha256-690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0"></a>
<a id="persistence-type-sha256-8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6"></a>
### `UserMessage[]`
SHA-256: `690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0`
SHA-256: `8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6`
Array of [`UserMessage`](#persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1).
Array of [`UserMessage`](#persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c).
<a id="persistence-type-sha256-c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896"></a>
@@ -5650,7 +5659,7 @@ Array of `number`.
SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b`
Sources: [`packages/api/session-controller/src/types.ts:389`](../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:21`](../packages/core/session/src/types.ts) · [`packages/experimental/webhook/src/brand.ts:12`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:6`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:9`](../packages/experimental/webhook/src/brand.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/jobs/jobs/src/brand.ts:19`](../packages/jobs/jobs/src/brand.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:14`](../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/team/agent-team/src/types.ts:20`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:32`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:8`](../packages/team/agent-team/src/types.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts)
Sources: [`packages/api/session-controller/src/types.ts:391`](../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:21`](../packages/core/session/src/types.ts) · [`packages/experimental/webhook/src/brand.ts:12`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:6`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:9`](../packages/experimental/webhook/src/brand.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/jobs/jobs/src/brand.ts:19`](../packages/jobs/jobs/src/brand.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:14`](../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/team/agent-team/src/types.ts:20`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:32`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:8`](../packages/team/agent-team/src/types.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts)
`string`
@@ -6425,18 +6434,18 @@ Sources: [`packages/core/session/src/types.ts:398`](../packages/core/session/src
| `reason` | required | [`RequestHeaderReason`](#persistence-type-sha256-530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6) |
| `startsSeries` | optional | `true` |
<a id="persistence-type-sha256-65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e"></a>
<a id="persistence-type-sha256-295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998"></a>
### `{ headerSeq?, message, step, turn }`
SHA-256: `65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e`
SHA-256: `295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998`
Sources: [`packages/core/session/src/types.ts:317`](../packages/core/session/src/types.ts)
| Property | Presence | Type |
|---|---|---|
| `headerSeq` | optional | `number` |
| `message` | required | [`DeveloperMessage`](#persistence-type-sha256-01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796) |
| `message` | required | [`DeveloperMessage`](#persistence-type-sha256-824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc) |
| `step` | required | `number` |
| `turn` | required | `number` |
@@ -6520,17 +6529,17 @@ Sources: [`packages/core/session/src/types.ts:435`](../packages/core/session/src
|---|---|---|
| `inherited` | optional | `true` |
<a id="persistence-type-sha256-e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51"></a>
<a id="persistence-type-sha256-f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492"></a>
### `{ inserted, outcome?, removedCount?, start, … }`
SHA-256: `e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51`
SHA-256: `f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492`
Sources: [`packages/core/agent/src/types.ts:110`](../packages/core/agent/src/types.ts)
| Property | Presence | Type |
|---|---|---|
| `inserted` | required | [`UserMessage[]`](#persistence-type-sha256-690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0) |
| `inserted` | required | [`UserMessage[]`](#persistence-type-sha256-8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6) |
| `outcome` | optional | `"canceled"` |
| `removedCount` | optional | `number` |
| `start` | required | `number` |
@@ -7290,6 +7299,21 @@ SHA-256: `db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c`
| `kind` | required | `"repeat-tool-reminder"` |
| `sections` | required | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) |
<a id="persistence-type-sha256-8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e"></a>
### `{ kind: "retry" }`
SHA-256: `8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e`
Sources: [`packages/api/session-controller/src/types.ts:402`](../packages/api/session-controller/src/types.ts)
| Property | Presence | Type |
|---|---|---|
| `clientTimeZone` | optional | `string` |
| `kind` | required | `"retry"` |
| `principal` | optional | [`union (2 variants)`](#persistence-type-sha256-824a4aad44a54e245c67196817d67946734a2dc0eee0b0b6834a5b2a6ef352ce) |
| `rpcId` | required | `string` |
<a id="persistence-type-sha256-0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789"></a>
### `{ kind: "runtime-context" }`
@@ -7800,7 +7824,7 @@ Sources: [`packages/core/tools/src/index.ts:28`](../packages/core/tools/src/inde
SHA-256: `a4afec59b75aad5d13ef82d6931f35cc2d98918503916cf069355b77c5e42302`
Sources: [`packages/api/session-controller/src/types.ts:398`](../packages/api/session-controller/src/types.ts)
Sources: [`packages/api/session-controller/src/types.ts:400`](../packages/api/session-controller/src/types.ts)
| Property | Presence | Type |
|---|---|---|
@@ -8189,17 +8213,17 @@ SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b`
| `time` | required | `number` |
| `type` | required | `"agent-preset/selected"` |
<a id="persistence-type-sha256-ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482"></a>
<a id="persistence-type-sha256-1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85"></a>
<a id="persistence-type-eventagentinboxspliced"></a>
### `{ type: "agent/inbox/spliced" }`
SHA-256: `ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482`
SHA-256: `1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85`
| Property | Presence | Type |
|---|---|---|
| `data` | required | [`{ inserted, outcome?, removedCount?, start, … }`](#persistence-type-sha256-e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51) |
| `data` | required | [`{ inserted, outcome?, removedCount?, start, … }`](#persistence-type-sha256-f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492) |
| `ignorable` | optional | `true` |
| `seq` | required | `number` |
| `time` | required | `number` |
@@ -8440,17 +8464,17 @@ SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176`
| `time` | required | `number` |
| `type` | required | `"deliverables/presented"` |
<a id="persistence-type-sha256-70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a"></a>
<a id="persistence-type-sha256-510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99"></a>
<a id="persistence-type-eventdevelopermessage"></a>
### `{ type: "developer/message" }`
SHA-256: `70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a`
SHA-256: `510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99`
| Property | Presence | Type |
|---|---|---|
| `data` | required | [`{ headerSeq?, message, step, turn }`](#persistence-type-sha256-65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e) |
| `data` | required | [`{ headerSeq?, message, step, turn }`](#persistence-type-sha256-295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998) |
| `ignorable` | optional | `true` |
| `seq` | required | `number` |
| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) |
@@ -8850,17 +8874,17 @@ SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5`
| `time` | required | `number` |
| `type` | required | `"session/title"` |
<a id="persistence-type-sha256-d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca"></a>
<a id="persistence-type-sha256-3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18"></a>
<a id="persistence-type-eventsessiontitle-llm-request"></a>
### `{ type: "session/title-llm-request" }`
SHA-256: `d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca`
SHA-256: `3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18`
| Property | Presence | Type |
|---|---|---|
| `data` | required | [`SessionTitleLlmRequestEventData`](#persistence-type-sha256-601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25) |
| `data` | required | [`SessionTitleLlmRequestEventData`](#persistence-type-sha256-bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4) |
| `ignorable` | optional | `true` |
| `seq` | required | `number` |
| `time` | required | `number` |
@@ -9299,17 +9323,17 @@ Sources: [`packages/llm/llm/src/types.ts:502`](../packages/llm/llm/src/types.ts)
| `type` | required | `"usage"` |
| `usage` | required | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) |
<a id="persistence-type-sha256-dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450"></a>
<a id="persistence-type-sha256-50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97"></a>
<a id="persistence-type-eventusermessage"></a>
### `{ type: "user/message" }`
SHA-256: `dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450`
SHA-256: `50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97`
| Property | Presence | Type |
|---|---|---|
| `data` | required | [`UserMessage`](#persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1) |
| `data` | required | [`UserMessage`](#persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c) |
| `ignorable` | optional | `true` |
| `seq` | required | `number` |
| `sourceEventSeqs` | optional | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) |
+69 -45
View File
@@ -25,7 +25,7 @@
| `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 | `ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482` | [`{ type: "agent/inbox/spliced" }`](#persistence-type-sha256-ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482) |
| `event:agent/inbox/spliced` | event | `1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85` | [`{ type: "agent/inbox/spliced" }`](#persistence-type-sha256-1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85) |
| `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) |
@@ -38,7 +38,7 @@
| `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 | `70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a` | [`{ type: "developer/message" }`](#persistence-type-sha256-70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a) |
| `event:developer/message` | event | `510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99` | [`{ type: "developer/message" }`](#persistence-type-sha256-510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99) |
| `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) |
@@ -60,7 +60,7 @@
| `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 | `d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca` | [`{ type: "session/title-llm-request" }`](#persistence-type-sha256-d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca) |
| `event:session/title-llm-request` | event | `3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18` | [`{ type: "session/title-llm-request" }`](#persistence-type-sha256-3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18) |
| `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 | `d49164d37eab0f0f70fa787c65d887abbea869c010ccb103d717fab3519c3a41` | [`{ type: "subagent/catalog" }`](#persistence-type-sha256-d49164d37eab0f0f70fa787c65d887abbea869c010ccb103d717fab3519c3a41) |
@@ -83,7 +83,7 @@
| `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 | `dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450` | [`{ type: "user/message" }`](#persistence-type-sha256-dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450) |
| `event:user/message` | event | `50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97` | [`{ type: "user/message" }`](#persistence-type-sha256-50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97) |
| `event:web/deepseek-search-llm-request` | event | `0c556c9b9f2a96238a6b9bbb99e748206cbff2ed6203041c9571f04ae5802f52` | [`{ type: "web/deepseek-search-llm-request" }`](#persistence-type-sha256-0c556c9b9f2a96238a6b9bbb99e748206cbff2ed6203041c9571f04ae5802f52) |
| `event:working-directory/change` | event | `124aa62078ca3311353b39cc3bf6c75da281338be6bbf672f8b361d828cddca3` | [`{ type: "working-directory/change" }`](#persistence-type-sha256-124aa62078ca3311353b39cc3bf6c75da281338be6bbf672f8b361d828cddca3) |
| `event:workspace/changes` | event | `e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72` | [`{ type: "workspace/changes" }`](#persistence-type-sha256-e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72) |
@@ -2448,6 +2448,14 @@ SHA-256: `34d1ab5c5df378186d6054b1a1beea9a41e41965d6f336f0bc0025c441a82e66`
`"resume"`
<a id="persistence-type-sha256-63ba8895cc09e4693cf0819fdcd18c084bef195febda5b6a23af279b3852be36"></a>
### `"retry"`
SHA-256: `63ba8895cc09e4693cf0819fdcd18c084bef195febda5b6a23af279b3852be36`
`"retry"`
<a id="persistence-type-sha256-24b10f7cdae64928f89c49afc2eca0af9eb4a2f135e16f3416e6b8461fef1748"></a>
### `"runtime-context"`
@@ -3420,7 +3428,7 @@ SHA-256: `abd6ca62a5ab166553848324a23fef90eed7f59c8021bd63e7ea5bc6fd666b0c`
| `body` | 必需 | [`{ max_tokens, messages, model, thinking?, … }`](#persistence-type-sha256-9c001ecb5e1d3c3894410db2a1e383842e5f8454fb52182338686158abc1b3ee) |
| `endpoint` | 必需 | `string` |
<a id="persistence-type-sha256-01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796"></a>
<a id="persistence-type-sha256-824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc"></a>
<a id="persistence-type-developermessage"></a>
@@ -3428,7 +3436,7 @@ SHA-256: `abd6ca62a5ab166553848324a23fef90eed7f59c8021bd63e7ea5bc6fd666b0c`
### `DeveloperMessage`
SHA-256: `01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796`
SHA-256: `824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc`
来源:[`packages/llm/llm/src/message.ts:157`](../packages/llm/llm/src/message.ts)
@@ -3437,7 +3445,7 @@ SHA-256: `01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796`
| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) |
| `id` | 必需 | `string` |
| `role` | 必需 | `"developer"` |
| `source` | 必需 | [`MessageSource`](#persistence-type-sha256-b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72) |
| `source` | 必需 | [`MessageSource`](#persistence-type-sha256-dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce) |
消息源兼容策略:`source` — `session-source-attribution` v1; `session.developer-message.source`; `kind`; `preserve`.
@@ -4136,7 +4144,7 @@ SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20`
| `step` | 必需 | `number` |
| `turn` | 必需 | `number` |
<a id="persistence-type-sha256-e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39"></a>
<a id="persistence-type-sha256-c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8"></a>
<a id="persistence-type-message"></a>
@@ -4144,15 +4152,15 @@ SHA-256: `6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20`
### `Message`
SHA-256: `e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39`
SHA-256: `c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8`
来源:[`packages/llm/llm/src/message.ts:196`](../packages/llm/llm/src/message.ts)
以下类型之一:
- [`ToolResultMessage`](#persistence-type-sha256-4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731)
- [`DeveloperMessage`](#persistence-type-sha256-01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796)
- [`UserMessage`](#persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1)
- [`DeveloperMessage`](#persistence-type-sha256-824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc)
- [`UserMessage`](#persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c)
- [`SystemMessage`](#persistence-type-sha256-09f3f8dc417f278257202714132f98ba7b52957d7b558c4a04456603890eb363)
- [`AssistantMessage`](#persistence-type-sha256-fa87537f4a9c1e25602990a8bf686b383e9e00352ec8946e16ae24ba7c1625be)
@@ -4229,7 +4237,7 @@ SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2`
- `"negative"`
- `"positive"`
<a id="persistence-type-sha256-b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72"></a>
<a id="persistence-type-sha256-dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce"></a>
<a id="persistence-type-messagesource"></a>
@@ -4237,7 +4245,7 @@ SHA-256: `390eed1028aba02774f14408647acec10ec5516e97d4f15ecde2b9989d5a69f2`
### `MessageSource`
SHA-256: `b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72`
SHA-256: `dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce`
来源:[`packages/llm/llm/src/message.ts:136`](../packages/llm/llm/src/message.ts)
@@ -4299,6 +4307,7 @@ SHA-256: `b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72`
| `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) |
| `retry` | 未声明 | `rpcId`: `string` | [`{ kind: "retry" }`](#persistence-type-sha256-8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e) |
| `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) |
@@ -4362,13 +4371,13 @@ SHA-256: `b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72`
| `webhook` | `"notice"` | `deliveryId`: `string`; `provider`: `string`; `ruleId`: `string`; `source`: `string`; `summary`: `string` | [`{ kind: "webhook", form: "notice" }`](#persistence-type-sha256-9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94) |
| `working-directory` | 未声明 | 无 | [`{ kind: "working-directory" }`](#persistence-type-sha256-2235d957bf4b7c6cf959231d480f0ba1f3a6d72d82981493fb6c7c963021d3d5) |
<a id="persistence-type-sha256-95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70"></a>
<a id="persistence-type-sha256-42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0"></a>
### `Message[]`
SHA-256: `95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70`
SHA-256: `42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0`
[`Message`](#persistence-type-sha256-e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39) 的数组。
[`Message`](#persistence-type-sha256-c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8) 的数组。
<a id="persistence-type-sha256-719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91"></a>
@@ -4736,7 +4745,7 @@ SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4`
| `source` | 必需 | [`SessionTitleSource`](#persistence-type-sha256-30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f) |
| `title` | 必需 | `string` |
<a id="persistence-type-sha256-601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25"></a>
<a id="persistence-type-sha256-bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4"></a>
<a id="persistence-type-packagessessionsession-title-llmsrcindextssessiontitlellmrequesteventdata"></a>
@@ -4744,7 +4753,7 @@ SHA-256: `b56f6a885da3dc394c69a3e3cc5c0cfc4da15601b63fda4989eee8f40efc5be4`
### `SessionTitleLlmRequestEventData`
SHA-256: `601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25`
SHA-256: `bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4`
来源:[`packages/session/session-title-llm/src/index.ts:43`](../packages/session/session-title-llm/src/index.ts)
@@ -4752,7 +4761,7 @@ SHA-256: `601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25`
|---|---|---|
| `maxTokens` | 必需 | `number` |
| `messageSeqs` | 必需 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) |
| `messages` | 必需 | [`Message[]`](#persistence-type-sha256-95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70) |
| `messages` | 必需 | [`Message[]`](#persistence-type-sha256-42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0) |
| `reasoningEffort` | 可选 | `string` |
| `route` | 必需 | [`SessionTitleModelIdentity`](#persistence-type-sha256-07e1a58c58b593f507b8e7f25723bb0aa42baae6e00f5ecfddf28cb1e64d3235) |
| `system` | 必需 | `string` |
@@ -5431,7 +5440,7 @@ SHA-256: `f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402`
| `interrupted` | 未声明 | 无 | [`{ kind: "interrupted" }`](#persistence-type-sha256-56b7c047694875a843ba020dfea3c8380d54ae4ff88ab349e72004dc21e07c23) |
| `max-tokens` | 未声明 | 无 | [`{ kind: "max-tokens" }`](#persistence-type-sha256-ab7ec5f9eb2c6dfacca5da4c37cf7ba85d04172053ee6b1ebf1709ffcd99c1a7) |
<a id="persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1"></a>
<a id="persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c"></a>
<a id="persistence-type-packagesllmllmsrcmessagetsusermessage"></a>
@@ -5439,7 +5448,7 @@ SHA-256: `f1687f982fa3d41ef29e159feed154ecd13af4dd209acaee16038f223f2e9402`
### `UserMessage`
SHA-256: `613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1`
SHA-256: `74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c`
来源:[`packages/llm/llm/src/message.ts:162`](../packages/llm/llm/src/message.ts)
@@ -5448,19 +5457,19 @@ SHA-256: `613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1`
| `content` | 必需 | [`ContentBlock[]`](#persistence-type-sha256-b52f215a6cd691058a3413c12f161fa3b563a2f4895adb3df6f744ec4b0a6ef1) |
| `id` | 必需 | `string` |
| `role` | 必需 | `"user"` |
| `source` | 必需 | [`MessageSource`](#persistence-type-sha256-b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72) |
| `source` | 必需 | [`MessageSource`](#persistence-type-sha256-dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce) |
消息源兼容策略:`source` — `session-source-attribution` v1; `session.user-message.source`; `kind`; `preserve`.
仅表示归属的新增 kind:`action-cards`, `tmux-context`, `user-question-reply`, `working-directory`.
<a id="persistence-type-sha256-690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0"></a>
<a id="persistence-type-sha256-8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6"></a>
### `UserMessage[]`
SHA-256: `690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0`
SHA-256: `8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6`
[`UserMessage`](#persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1) 的数组。
[`UserMessage`](#persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c) 的数组。
<a id="persistence-type-sha256-c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896"></a>
@@ -5652,7 +5661,7 @@ SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78`
SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b`
来源:[`packages/api/session-controller/src/types.ts:389`](../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:21`](../packages/core/session/src/types.ts) · [`packages/experimental/webhook/src/brand.ts:12`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:6`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:9`](../packages/experimental/webhook/src/brand.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/jobs/jobs/src/brand.ts:19`](../packages/jobs/jobs/src/brand.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:14`](../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/team/agent-team/src/types.ts:20`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:32`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:8`](../packages/team/agent-team/src/types.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts)
来源:[`packages/api/session-controller/src/types.ts:391`](../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:21`](../packages/core/session/src/types.ts) · [`packages/experimental/webhook/src/brand.ts:12`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:6`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:9`](../packages/experimental/webhook/src/brand.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/jobs/jobs/src/brand.ts:19`](../packages/jobs/jobs/src/brand.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:14`](../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/team/agent-team/src/types.ts:20`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:32`](../packages/team/agent-team/src/types.ts) · [`packages/team/agent-team/src/types.ts:8`](../packages/team/agent-team/src/types.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts)
`string`
@@ -6427,18 +6436,18 @@ SHA-256: `ad0c38a0adb82a94c925456df41586d9b5f9202fca18593eae2213d4445b4585`
| `reason` | 必需 | [`RequestHeaderReason`](#persistence-type-sha256-530da6c0267813bb4511af72883cc518834e624e3b3220a7062955fd57a788a6) |
| `startsSeries` | 可选 | `true` |
<a id="persistence-type-sha256-65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e"></a>
<a id="persistence-type-sha256-295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998"></a>
### `{ headerSeq?, message, step, turn }`
SHA-256: `65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e`
SHA-256: `295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998`
来源:[`packages/core/session/src/types.ts:317`](../packages/core/session/src/types.ts)
| 属性 | 存在性 | 类型 |
|---|---|---|
| `headerSeq` | 可选 | `number` |
| `message` | 必需 | [`DeveloperMessage`](#persistence-type-sha256-01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796) |
| `message` | 必需 | [`DeveloperMessage`](#persistence-type-sha256-824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc) |
| `step` | 必需 | `number` |
| `turn` | 必需 | `number` |
@@ -6522,17 +6531,17 @@ SHA-256: `17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3`
|---|---|---|
| `inherited` | 可选 | `true` |
<a id="persistence-type-sha256-e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51"></a>
<a id="persistence-type-sha256-f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492"></a>
### `{ inserted, outcome?, removedCount?, start, … }`
SHA-256: `e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51`
SHA-256: `f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492`
来源:[`packages/core/agent/src/types.ts:110`](../packages/core/agent/src/types.ts)
| 属性 | 存在性 | 类型 |
|---|---|---|
| `inserted` | 必需 | [`UserMessage[]`](#persistence-type-sha256-690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0) |
| `inserted` | 必需 | [`UserMessage[]`](#persistence-type-sha256-8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6) |
| `outcome` | 可选 | `"canceled"` |
| `removedCount` | 可选 | `number` |
| `start` | 必需 | `number` |
@@ -7292,6 +7301,21 @@ SHA-256: `db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c`
| `kind` | 必需 | `"repeat-tool-reminder"` |
| `sections` | 必需 | [`ContextSnapshotSection[]`](#persistence-type-sha256-c748fb42c80a120038a8c587af80ec39924803c401364db11c8974d5bf6d0262) |
<a id="persistence-type-sha256-8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e"></a>
### `{ kind: "retry" }`
SHA-256: `8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e`
来源:[`packages/api/session-controller/src/types.ts:402`](../packages/api/session-controller/src/types.ts)
| 属性 | 存在性 | 类型 |
|---|---|---|
| `clientTimeZone` | 可选 | `string` |
| `kind` | 必需 | `"retry"` |
| `principal` | 可选 | [`union (2 variants)`](#persistence-type-sha256-824a4aad44a54e245c67196817d67946734a2dc0eee0b0b6834a5b2a6ef352ce) |
| `rpcId` | 必需 | `string` |
<a id="persistence-type-sha256-0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789"></a>
### `{ kind: "runtime-context" }`
@@ -7802,7 +7826,7 @@ SHA-256: `8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543`
SHA-256: `a4afec59b75aad5d13ef82d6931f35cc2d98918503916cf069355b77c5e42302`
来源:[`packages/api/session-controller/src/types.ts:398`](../packages/api/session-controller/src/types.ts)
来源:[`packages/api/session-controller/src/types.ts:400`](../packages/api/session-controller/src/types.ts)
| 属性 | 存在性 | 类型 |
|---|---|---|
@@ -8191,17 +8215,17 @@ SHA-256: `a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b`
| `time` | 必需 | `number` |
| `type` | 必需 | `"agent-preset/selected"` |
<a id="persistence-type-sha256-ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482"></a>
<a id="persistence-type-sha256-1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85"></a>
<a id="persistence-type-eventagentinboxspliced"></a>
### `{ type: "agent/inbox/spliced" }`
SHA-256: `ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482`
SHA-256: `1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85`
| 属性 | 存在性 | 类型 |
|---|---|---|
| `data` | 必需 | [`{ inserted, outcome?, removedCount?, start, … }`](#persistence-type-sha256-e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51) |
| `data` | 必需 | [`{ inserted, outcome?, removedCount?, start, … }`](#persistence-type-sha256-f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492) |
| `ignorable` | 可选 | `true` |
| `seq` | 必需 | `number` |
| `time` | 必需 | `number` |
@@ -8442,17 +8466,17 @@ SHA-256: `13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176`
| `time` | 必需 | `number` |
| `type` | 必需 | `"deliverables/presented"` |
<a id="persistence-type-sha256-70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a"></a>
<a id="persistence-type-sha256-510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99"></a>
<a id="persistence-type-eventdevelopermessage"></a>
### `{ type: "developer/message" }`
SHA-256: `70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a`
SHA-256: `510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99`
| 属性 | 存在性 | 类型 |
|---|---|---|
| `data` | 必需 | [`{ headerSeq?, message, step, turn }`](#persistence-type-sha256-65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e) |
| `data` | 必需 | [`{ headerSeq?, message, step, turn }`](#persistence-type-sha256-295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998) |
| `ignorable` | 可选 | `true` |
| `seq` | 必需 | `number` |
| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) |
@@ -8852,17 +8876,17 @@ SHA-256: `1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5`
| `time` | 必需 | `number` |
| `type` | 必需 | `"session/title"` |
<a id="persistence-type-sha256-d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca"></a>
<a id="persistence-type-sha256-3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18"></a>
<a id="persistence-type-eventsessiontitle-llm-request"></a>
### `{ type: "session/title-llm-request" }`
SHA-256: `d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca`
SHA-256: `3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18`
| 属性 | 存在性 | 类型 |
|---|---|---|
| `data` | 必需 | [`SessionTitleLlmRequestEventData`](#persistence-type-sha256-601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25) |
| `data` | 必需 | [`SessionTitleLlmRequestEventData`](#persistence-type-sha256-bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4) |
| `ignorable` | 可选 | `true` |
| `seq` | 必需 | `number` |
| `time` | 必需 | `number` |
@@ -9301,17 +9325,17 @@ SHA-256: `f1a96afe7503ac1817de769cd0ba13d9b80111c7034c50106b3344ecc14cc515`
| `type` | 必需 | `"usage"` |
| `usage` | 必需 | [`TokenUsage`](#persistence-type-sha256-fec5442b9ee4122e10514d81d5a43648003fe8bfb7ee2ba50c0cdbdd383ed394) |
<a id="persistence-type-sha256-dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450"></a>
<a id="persistence-type-sha256-50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97"></a>
<a id="persistence-type-eventusermessage"></a>
### `{ type: "user/message" }`
SHA-256: `dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450`
SHA-256: `50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97`
| 属性 | 存在性 | 类型 |
|---|---|---|
| `data` | 必需 | [`UserMessage`](#persistence-type-sha256-613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1) |
| `data` | 必需 | [`UserMessage`](#persistence-type-sha256-74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c) |
| `ignorable` | 可选 | `true` |
| `seq` | 必需 | `number` |
| `sourceEventSeqs` | 可选 | [`number[]`](#persistence-type-sha256-5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78) |
@@ -0,0 +1,28 @@
# Bilingual-pair consistency record for 2026-10-27-retry-control-input.md (docs/i18n/README.md): per heading
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
# After editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/persistence-changes/2026-10-27-retry-control-input.md
/:
en: 3d5a424ae7d7e46b
zh: c22a8e4a62d8cc1a
/2026-10-27-retry-control-input:
en: 32c7e9cc4a9f86b4
zh: f1cb7169df15e8e4
/2026-10-27-retry-control-input/summary:
en: 77dd9a1b2db8d968
zh: c3d0111e34b27fe3
/2026-10-27-retry-control-input/table-of-contents:
en: 6cf314a069ceb451
zh: 9adff678e9ecab3b
/2026-10-27-retry-control-input/declaration:
en: 6907136f28e48c90
zh: 02f8298485f3d8e7
/2026-10-27-retry-control-input/compatibility:
en: 6dee29fbf0f77087
zh: 72e0cfdef298a75e
/2026-10-27-retry-control-input/verification:
en: 06eee3f214f278b8
zh: d044457dd6e5b8c3
/2026-10-27-retry-control-input/dev-note:
en: b75c8458928b72b9
zh: 003ba4e17b4b5269
@@ -0,0 +1,60 @@
---
description: "Records a persistence type transition and its compatibility acknowledgement."
kind: persistence-change
---
# 2026-10-27-retry-control-input
English | [中文](2026-10-27-retry-control-input.zh.md)
## Summary
Add the retry message source for empty Session API continuation prompts; ordinary user/message records retain the input identity and caller metadata.
## Table of Contents
- [Declaration](#declaration)
- [Compatibility](#compatibility)
- [Verification](#verification)
- [Dev Note](#dev-note)
<a id="declaration"></a>
## Declaration
```yaml persistence-change
schemaVersion: 1
id: 2026-10-27-retry-control-input
baseline: false
changes:
- root: "event:agent/inbox/spliced"
previous: "2026-10-27-subagent-settlement-attribution"
after: "1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85"
decision: same-version
- root: "event:developer/message"
previous: "2026-10-27-subagent-settlement-attribution"
after: "510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99"
decision: same-version
- root: "event:session/title-llm-request"
previous: "2026-10-27-subagent-settlement-attribution"
after: "3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18"
decision: same-version
- root: "event:user/message"
previous: "2026-10-27-subagent-settlement-attribution"
after: "50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97"
decision: same-version
```
<a id="compatibility"></a>
## Compatibility
The retry source is producer-owned metadata on the existing empty UserMessage representation. AgentLoop, model-history derivation, and SDK prompt behavior are unchanged. Older readers preserve extensible source metadata and consume these messages through ordinary user-message admission; they may display an empty context row. Updated readers retain historical ordinary messages and hide only empty retry messages in Chat. Existing event discriminators and the current Session version remain unchanged; no new required event is introduced.
<a id="verification"></a>
## Verification
The Session API suite passed 1112 tests across 51 files; continuation.ts has 100% statements, branches, functions, and lines. Chat and conversation tests passed 1875 tests across 113 files; final focused Chat and input regressions passed 96 and 31 tests. The browser continuation replay passed with an empty retry user message retained in the log, no empty Chat bubble, and normally closed turns. Build passed all 10 gates, typed lint exited 0, and doc-sync passed all 43 gates. Git comparison against the PR base confirms no AgentLoop, Core Agent, Core Session, or SDK changes.
<a id="dev-note"></a>
## Dev Note
None.
@@ -0,0 +1,261 @@
{
"formatVersion": 2,
"roots": [
{"key":"event:agent/inbox/spliced","kind":"event","event":"agent/inbox/spliced","surface":false,"digest":"1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85"},
{"key":"event:developer/message","kind":"event","event":"developer/message","surface":true,"digest":"510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99"},
{"key":"event:session/title-llm-request","kind":"event","event":"session/title-llm-request","surface":false,"digest":"3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18"},
{"key":"event:user/message","kind":"event","event":"user/message","surface":true,"digest":"50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97"}
],
"types": [],
"nodes": {
"0203243b72fc867a": {"kind":"object","properties":[{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
"022623b9ef98ec47": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"02b2c23f2d94b028": {"kind":"object","properties":[{"name":"kind","type":"c5687b1313206a6f","optional":false}],"indices":[]},
"05205074b24d8340": {"kind":"literal","value":"action-cards"},
"0657d3ca5ac4e7bf": {"kind":"primitive","type":"number"},
"07e1a58c58b593f5": {"kind":"object","properties":[{"name":"model","type":"4cd48f3e5108bd6e","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"09655b34d7f3cf1e": {"kind":"literal","value":"system-prompt"},
"09f3f8dc417f2782": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"8af841fc9b265ade","optional":false},{"name":"source","type":"65a8400e451e667e","optional":false}],"indices":[]},
"0a92c5bdfa06c2e2": {"kind":"object","properties":[{"name":"displayName","type":"4cd48f3e5108bd6e","optional":true},{"name":"providerId","type":"4cd48f3e5108bd6e","optional":false},{"name":"subjectId","type":"4cd48f3e5108bd6e","optional":false},{"name":"tenantId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"0ed8d1108fe7a5e1": {"kind":"object","properties":[{"name":"kind","type":"a9059a81430b3207","optional":false}],"indices":[]},
"0eeb17e1df89b1eb": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
"0f46153645c29784": {"kind":"object","properties":[{"name":"height","type":"0657d3ca5ac4e7bf","optional":false},{"name":"width","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"0fe52387f6505270": {"kind":"literal","value":"plan-mode"},
"11638dc58a31496f": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"12d5808fac1996b9": {"kind":"object","properties":[{"name":"attachment","type":"b0b0eb1b16490f6b","optional":false},{"name":"offloaded","type":"dacf3d5f3e4ff619","optional":true},{"name":"type","type":"fb8b6a2e53cb9cf4","optional":false}],"indices":[]},
"1379f0b72275994d": {"kind":"literal","value":"developer/message"},
"1682631f010d5ea7": {"kind":"object","properties":[{"name":"data","type":"f7752f518bb2f916","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"829a2fb3be6efd4b","optional":false}],"indices":[]},
"16d0507cb94b4cfc": {"kind":"literal","value":"relay"},
"1922cd79a70806c1": {"kind":"literal","value":"skill-invocation"},
"1938c8c20f1cba7c": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false}],"indices":[]},
"1e0b0b66b6f0c53f": {"kind":"literal","value":"aborted"},
"1e709346005826eb": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false}],"indices":[]},
"1ebc6f9ff3aa9e3a": {"kind":"literal","value":"completed"},
"1f0133217eeeffd8": {"kind":"literal","value":"tool-call"},
"1f1385dbc3e875c0": {"kind":"literal","value":"repeat-tool-reminder"},
"1fdad624334d3548": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false}],"indices":[]},
"2152caf1a71e588e": {"kind":"object","properties":[{"name":"kind","type":"2e4debca12f2c449","optional":false},{"name":"messageId","type":"4cd48f3e5108bd6e","optional":false},{"name":"senderId","type":"4cd48f3e5108bd6e","optional":false},{"name":"senderName","type":"4cd48f3e5108bd6e","optional":false},{"name":"teamId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"2235d957bf4b7c6c": {"kind":"object","properties":[{"name":"kind","type":"7b1ce60193fa8b69","optional":false}],"indices":[]},
"224aa11d4d5f88c4": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"23af3759678a30de","optional":false}],"indices":[]},
"23af3759678a30de": {"kind":"literal","value":"dsh-session-title-llm"},
"24b10f7cdae64928": {"kind":"literal","value":"runtime-context"},
"24ce31aa528272e5": {"kind":"object","properties":[{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"260523b412c19ad8": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"2765e9119edf5816": {"kind":"literal","value":"model"},
"277b61f9c6f81704": {"kind":"literal","value":"file"},
"28936c614bd4e7e2": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"290f32bfd81ff85a": {"kind":"object","properties":[{"name":"kind","type":"23af3759678a30de","optional":false}],"indices":[]},
"295809283ede248d": {"kind":"object","properties":[{"name":"headerSeq","type":"0657d3ca5ac4e7bf","optional":true},{"name":"message","type":"824b1d4d4f007bda","optional":false},{"name":"step","type":"0657d3ca5ac4e7bf","optional":false},{"name":"turn","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"297fbd8067d7815a": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false}],"indices":[]},
"2aad1179f9576314": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"2ab12a0e345658f9": {"kind":"array","element":"83da72c6857601c7"},
"2e4debca12f2c449": {"kind":"literal","value":"team-message"},
"2f1e6a7ebace43d7": {"kind":"union","types":["3f74ba74acd10644","58f94390b982f8a5","de30b1fa12c75f81","ebb768d85ec87fb6"]},
"2f3f201c8846e19c": {"kind":"literal","value":"tool-goal"},
"312aee2f0c42aabb": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"31907de956375182": {"kind":"object","properties":[{"name":"compactionId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"6b23ed9ce1b397e6","optional":false},{"name":"sourceCommandId","type":"4cd48f3e5108bd6e","optional":true}],"indices":[]},
"3247e566f4340029": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"335e242de1fcc17b": {"kind":"union","types":["bcf0caf62d964b2f","e438a9d4fb883b3e"]},
"383cf73ae4748e5b": {"kind":"literal","value":"recall"},
"3b04790e08b35241": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false}],"indices":[]},
"3b4f2c9ef2c1217e": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false}],"indices":[]},
"3bca25b2baa6b22b": {"kind":"object","properties":[{"name":"data","type":"bec5ca3a376f56f3","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"587bb11da730e06a","optional":false}],"indices":[]},
"3bd652ebfa8726b3": {"kind":"union","types":["0657d3ca5ac4e7bf","938f7c7357bc403e"]},
"3bdb8dc6989655b0": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"3c2535ca0a2062f1": {"kind":"literal","value":"reasoning"},
"3e2ece4967cfebe9": {"kind":"literal","value":"next-step"},
"3f74ba74acd10644": {"kind":"literal","value":"image/jpeg"},
"408927267422a7b2": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false}],"indices":[]},
"42e2ff61928fb7df": {"kind":"array","element":"c51f0d0a405bb96f"},
"43e311235aa537df": {"kind":"object","properties":[{"name":"toolName","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"83d6916021eede8f","optional":false}],"indices":[]},
"45f005e6bbb76452": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"4991dfc415c9efeb": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"49dab019d00e8c26": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"78a9be340090b735","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"4a561c111a78d452": {"kind":"literal","value":"refusal"},
"4a9bef9f27a94252": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"82470020b5bfcb1a","optional":false},{"name":"senderSessionId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"4b259f7f8f0a44ad": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"isError","type":"aa93010d0e521ad7","optional":true},{"name":"role","type":"a13d8f379222ece8","optional":false},{"name":"source","type":"d9c462b9f62fdd3e","optional":false},{"name":"toolCallId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"4cd48f3e5108bd6e": {"kind":"primitive","type":"string"},
"4d60dddaa65d3da8": {"kind":"object","properties":[{"name":"actor","type":"0a92c5bdfa06c2e2","optional":false},{"name":"kind","type":"6ba7edb6447b6a3e","optional":false},{"name":"shareId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"4e44c9118152f682": {"kind":"literal","value":"text"},
"4e88776858652856": {"kind":"object","properties":[{"name":"text","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"4e44c9118152f682","optional":false}],"indices":[]},
"4edec1b770e8ec4c": {"kind":"literal","value":"ptc-mode"},
"4f91f187baeabef5": {"kind":"object","properties":[{"name":"capturedFormatVersion","type":"0657d3ca5ac4e7bf","optional":true},{"name":"capturedThroughSeq","type":"3bd652ebfa8726b3","optional":false},{"name":"compacted","type":"aa93010d0e521ad7","optional":false},{"name":"inputIndex","type":"0657d3ca5ac4e7bf","optional":false},{"name":"label","type":"4cd48f3e5108bd6e","optional":false},{"name":"omittedBytes","type":"0657d3ca5ac4e7bf","optional":false},{"name":"omittedMessages","type":"0657d3ca5ac4e7bf","optional":false},{"name":"originalMessages","type":"0657d3ca5ac4e7bf","optional":false},{"name":"retainedMessages","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sessionId","type":"4cd48f3e5108bd6e","optional":false},{"name":"truncated","type":"aa93010d0e521ad7","optional":false}],"indices":[]},
"50a15408d511e9be": {"kind":"object","properties":[{"name":"data","type":"74e0e5885d2ddf04","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"de25352d2dc41963","optional":false}],"indices":[]},
"510826cf4e1f9220": {"kind":"object","properties":[{"name":"data","type":"295809283ede248d","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"1379f0b72275994d","optional":false}],"indices":[]},
"52c6113cb0e53f34": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"9ac52f0f84fec2eb","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"53cf1704ae0709c7": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"5654685d7557ec74": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"58015da1c1950a66": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
"587bb11da730e06a": {"kind":"literal","value":"session/title-llm-request"},
"589d0d91239681f8": {"kind":"literal","value":"developer"},
"58f94390b982f8a5": {"kind":"literal","value":"image/png"},
"5bb69b88517f6214": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"5bc66269cfaf614c": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false}],"indices":[]},
"5cdbf342b7748d15": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"5d03ba38734809bc": {"kind":"array","element":"0657d3ca5ac4e7bf"},
"5d7a64ed6aac5551": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
"6085488d223aeffd": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"6292bcbedaa97fea": {"kind":"object","properties":[{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"62ecb62dc0fe1b5e": {"kind":"literal","value":"next-turn"},
"63ba8895cc09e469": {"kind":"literal","value":"retry"},
"65a8400e451e667e": {"kind":"object","properties":[{"name":"kind","type":"09655b34d7f3cf1e","optional":false}],"indices":[]},
"65d583e66518c523": {"kind":"object","properties":[{"name":"entries","type":"aba175fb20ffc711","optional":false},{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"incomplete","type":"dacf3d5f3e4ff619","optional":true},{"name":"kind","type":"6ebcc2dbec9f2dab","optional":false},{"name":"update","type":"dacf3d5f3e4ff619","optional":true}],"indices":[]},
"672c4aa2a9b736e3": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"1922cd79a70806c1","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"68141cbe3994a5ff": {"kind":"literal","value":"max-tokens"},
"68f44f59e91c4139": {"kind":"literal","value":"user"},
"6b23ed9ce1b397e6": {"kind":"literal","value":"compact-checkpoint"},
"6ba7edb6447b6a3e": {"kind":"literal","value":"share-viewer"},
"6ccb6bc423fb3952": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"6ea608bdc8a7a63d": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false}],"indices":[]},
"6ebcc2dbec9f2dab": {"kind":"literal","value":"skill-catalog"},
"6f22a9d02b9a1f11": {"kind":"object","properties":[{"name":"baseline","type":"dacf3d5f3e4ff619","optional":true},{"name":"baselineIdentity","type":"4cd48f3e5108bd6e","optional":true},{"name":"changes","type":"2ab12a0e345658f9","optional":false},{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"fbd2c74b346a1595","optional":false}],"indices":[]},
"6f44f32be9bcd9a8": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"6f9e00383836275e": {"kind":"literal","value":"snapshot"},
"719c51f67074f970": {"kind":"object","properties":[{"name":"kind","type":"2765e9119edf5816","optional":false},{"name":"model","type":"4cd48f3e5108bd6e","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false},{"name":"replayState","type":"bbc5696e3f13c758","optional":true}],"indices":[]},
"7382c4fc95fe8c5d": {"kind":"literal","value":"remove"},
"74e0e5885d2ddf04": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"68f44f59e91c4139","optional":false},{"name":"source","type":"dca3ba43188095fa","optional":false,"compatibility":{"version":1,"policy":"session-source-attribution","binding":"session.user-message.source","discriminator":"kind","unknownKinds":"preserve","attributionKinds":["action-cards","tmux-context","user-question-reply","working-directory"]}}],"indices":[]},
"7554565be416b034": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"756b5e23a5cb2c7f": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
"78a9be340090b735": {"kind":"literal","value":"tmux-context"},
"7b1ce60193fa8b69": {"kind":"literal","value":"working-directory"},
"7df62978a2b7de85": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"78a9be340090b735","optional":false}],"indices":[]},
"7eaef7a763ba5b94": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"23af3759678a30de","optional":false}],"indices":[]},
"7f13860ee89a2d35": {"kind":"literal","value":"session-reference"},
"7f959241c24128b4": {"kind":"object","properties":[{"name":"goalId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"b815d7b91cdd9fc6","optional":false},{"name":"revision","type":"0657d3ca5ac4e7bf","optional":false},{"name":"round","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"8064c03c87c357fd": {"kind":"union","types":["12d5808fac1996b9","43e311235aa537df","4e88776858652856","814d9434e1ddf907","8e611bf46821e500","c1f0f17b6493b85d","f2da0f27c1e6add5"]},
"80677c8c8b804189": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"23af3759678a30de","optional":false}],"indices":[]},
"8067b0d232c350f1": {"kind":"literal","value":"time-context"},
"814d9434e1ddf907": {"kind":"object","properties":[{"name":"text","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"3c2535ca0a2062f1","optional":false}],"indices":[]},
"82470020b5bfcb1a": {"kind":"literal","value":"agent-message"},
"824a4aad44a54e24": {"kind":"union","types":["4d60dddaa65d3da8","deebfc7c62177ea8"]},
"824b1d4d4f007bda": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"589d0d91239681f8","optional":false},{"name":"source","type":"dca3ba43188095fa","optional":false,"compatibility":{"version":1,"policy":"session-source-attribution","binding":"session.developer-message.source","discriminator":"kind","unknownKinds":"preserve","attributionKinds":["action-cards","tmux-context","user-question-reply","working-directory"]}}],"indices":[]},
"825ca23416b1ea9d": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"829a2fb3be6efd4b": {"kind":"literal","value":"agent/inbox/spliced"},
"83079c8a3f733ac3": {"kind":"object","properties":[{"name":"description","type":"4cd48f3e5108bd6e","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"8338ee303e2bd448": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"23af3759678a30de","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"83d6916021eede8f": {"kind":"literal","value":"tool-removal"},
"83da72c6857601c7": {"kind":"object","properties":[{"name":"action","type":"904bf499d98be4a3","optional":false},{"name":"digest","type":"4cd48f3e5108bd6e","optional":true},{"name":"path","type":"4cd48f3e5108bd6e","optional":false},{"name":"scope","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"848639f8787f035b": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"bf16d2e98a7f1389","optional":false},{"name":"senderSessionId","type":"4cd48f3e5108bd6e","optional":false},{"name":"stopReason","type":"866f7b2dbdc5b421","optional":true},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"854db3efdfb0cd39": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"85d6d96ff8842974": {"kind":"literal","value":"answered"},
"85f9b505b7bdff1f": {"kind":"literal","value":"tool-addition"},
"85fe96bf15d5c755": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
"8620189c8e335827": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"866f7b2dbdc5b421": {"kind":"union","types":["1e0b0b66b6f0c53f","1ebc6f9ff3aa9e3a","4a561c111a78d452","68141cbe3994a5ff","a2be0f0cb59f0d4a"]},
"86e1e384495ee09a": {"kind":"object","properties":[{"name":"name","type":"4cd48f3e5108bd6e","optional":false},{"name":"text","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"87b1a33564b9a4d6": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false}],"indices":[]},
"88841202942c7683": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"8a046b52331959aa": {"kind":"object","properties":[{"name":"kind","type":"78a9be340090b735","optional":false}],"indices":[]},
"8a54d228b1b7d845": {"kind":"array","element":"74e0e5885d2ddf04"},
"8af841fc9b265ade": {"kind":"literal","value":"system"},
"8c1c4f72755a78ea": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"8c627d7a45fa406c": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"8e611bf46821e500": {"kind":"object","properties":[{"name":"tool","type":"fcf427290c6213c2","optional":true},{"name":"toolName","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"85f9b505b7bdff1f","optional":false}],"indices":[]},
"8f1062573ea91841": {"kind":"object","properties":[{"name":"clientTimeZone","type":"4cd48f3e5108bd6e","optional":true},{"name":"kind","type":"63ba8895cc09e469","optional":false},{"name":"principal","type":"824a4aad44a54e24","optional":true},{"name":"rpcId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"8f324cea3916c051": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"8fcb0b44a575e998": {"kind":"object","properties":[{"name":"kind","type":"a720757f704a2512","optional":false}],"indices":[]},
"904bf499d98be4a3": {"kind":"union","types":["7382c4fc95fe8c5d","b765ee31033cea46","f6cb462f808309e3"]},
"938f7c7357bc403e": {"kind":"primitive","type":"null"},
"95a3ffccbf3c8afc": {"kind":"literal","value":"owner"},
"95c0e88fcf0bafb2": {"kind":"literal","value":"assistant"},
"9645cf93769a6dfb": {"kind":"literal","value":"user-question-reply"},
"96bfb916a727cd44": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
"96f4a9c81fc0f940": {"kind":"union","types":["3e2ece4967cfebe9","62ecb62dc0fe1b5e"]},
"99135d8a39379779": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"9ac52f0f84fec2eb","optional":false}],"indices":[]},
"99e7e7d7fed55ae6": {"kind":"literal","value":"tool-jobs"},
"99f0e98184709ad1": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false}],"indices":[]},
"9ac52f0f84fec2eb": {"kind":"literal","value":"model-selection"},
"9edc162949abf93b": {"kind":"object","properties":[{"name":"deliveryId","type":"4cd48f3e5108bd6e","optional":false},{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"db6c5246911d47a7","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false},{"name":"ruleId","type":"4cd48f3e5108bd6e","optional":false},{"name":"source","type":"4cd48f3e5108bd6e","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"9f65c43e340bba31": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"78a9be340090b735","optional":false}],"indices":[]},
"a13d8f379222ece8": {"kind":"literal","value":"tool"},
"a15a19ef63cf5d1b": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"9ac52f0f84fec2eb","optional":false}],"indices":[]},
"a16e567c8cd2c55c": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false}],"indices":[]},
"a2066bd52f61218b": {"kind":"object","properties":[{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"a2be0f0cb59f0d4a": {"kind":"literal","value":"error"},
"a3c6f1ea38e9a61d": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"9ac52f0f84fec2eb","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"a4afec59b75aad5d": {"kind":"object","properties":[{"name":"clientTimeZone","type":"4cd48f3e5108bd6e","optional":true},{"name":"kind","type":"68f44f59e91c4139","optional":false},{"name":"principal","type":"824a4aad44a54e24","optional":true},{"name":"rpcId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"a720757f704a2512": {"kind":"literal","value":"tool-registry"},
"a9059a81430b3207": {"kind":"literal","value":"hooks-claude-code"},
"aa2bf9e82b9fdeb9": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"aa93010d0e521ad7": {"kind":"primitive","type":"boolean"},
"aae343bc3d663c83": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"9ac52f0f84fec2eb","optional":false}],"indices":[]},
"aba175fb20ffc711": {"kind":"array","element":"83079c8a3f733ac3"},
"ada310bf0bdb8fed": {"kind":"object","properties":[{"name":"kind","type":"68f44f59e91c4139","optional":false}],"indices":[]},
"ade057f4fdc387ae": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"aec150797b655c5f": {"kind":"literal","value":"catalog"},
"b062078e899958f9": {"kind":"object","properties":[{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"b0b0eb1b16490f6b": {"kind":"object","properties":[{"name":"attachmentId","type":"4cd48f3e5108bd6e","optional":false},{"name":"bytes","type":"0657d3ca5ac4e7bf","optional":false},{"name":"height","type":"0657d3ca5ac4e7bf","optional":false},{"name":"mediaType","type":"2f1e6a7ebace43d7","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":true},{"name":"originalDimensions","type":"0f46153645c29784","optional":true},{"name":"width","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"b2a5c8c008a31e3d": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"23af3759678a30de","optional":false}],"indices":[]},
"b3681c026a0b98e9": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"78a9be340090b735","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"b4ec0af39fd52ed9": {"kind":"object","properties":[{"name":"kind","type":"bb94f3217aa56c88","optional":false}],"indices":[]},
"b52f215a6cd69105": {"kind":"array","element":"8064c03c87c357fd"},
"b613f83572fe2fbf": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"b6f94c17dd9bbd7c": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false}],"indices":[]},
"b70f3e81fe11b7a5": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false}],"indices":[]},
"b765ee31033cea46": {"kind":"literal","value":"set"},
"b79641a9d25e7566": {"kind":"object","properties":[{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
"b815d7b91cdd9fc6": {"kind":"literal","value":"goal"},
"ba2a1a8f194b1bb2": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"ba4c40b4381e0dcd": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"23af3759678a30de","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"baccc97ec34be6c4": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"bb94f3217aa56c88": {"kind":"literal","value":"hooks-codex"},
"bbc5696e3f13c758": {"kind":"opaque","reason":"unknown"},
"bcf0caf62d964b2f": {"kind":"object","properties":[{"name":"endSeq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"op","type":"f6cb462f808309e3","optional":false},{"name":"startSeq","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"bec5ca3a376f56f3": {"kind":"object","properties":[{"name":"maxTokens","type":"0657d3ca5ac4e7bf","optional":false},{"name":"messageSeqs","type":"5d03ba38734809bc","optional":false},{"name":"messages","type":"42e2ff61928fb7df","optional":false},{"name":"reasoningEffort","type":"4cd48f3e5108bd6e","optional":true},{"name":"route","type":"07e1a58c58b593f5","optional":false},{"name":"system","type":"4cd48f3e5108bd6e","optional":false},{"name":"titleProvider","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"bf16d2e98a7f1389": {"kind":"literal","value":"subagent-settled"},
"c1f0f17b6493b85d": {"kind":"object","properties":[{"name":"arguments","type":"4cd48f3e5108bd6e","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"1f0133217eeeffd8","optional":false}],"indices":[]},
"c51f0d0a405bb96f": {"kind":"union","types":["09f3f8dc417f2782","4b259f7f8f0a44ad","74e0e5885d2ddf04","824b1d4d4f007bda","fa87537f4a9c1e25"]},
"c5228b7a55498d84": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"c55827fba7018198": {"kind":"object","properties":[{"name":"callId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"9645cf93769a6dfb","optional":false},{"name":"outcome","type":"85d6d96ff8842974","optional":false}],"indices":[]},
"c5687b1313206a6f": {"kind":"literal","value":"cordis-host-runner"},
"c748fb42c80a1200": {"kind":"array","element":"86e1e384495ee09a"},
"cb1c8959e1726f82": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
"cda2345a9be9d139": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"d4e4d575abeb4b72": {"kind":"literal","value":"canceled"},
"d85590a5675c6e2f": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"d9c462b9f62fdd3e": {"kind":"object","properties":[{"name":"callId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"a13d8f379222ece8","optional":false}],"indices":[]},
"d9edf1862e4471d6": {"kind":"literal","value":"schedule"},
"dacf3d5f3e4ff619": {"kind":"literal","value":true},
"db06ef35b27a3842": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"db6c5246911d47a7": {"kind":"literal","value":"webhook"},
"dba54c09c6e7aafc": {"kind":"object","properties":[{"name":"kind","type":"4edec1b770e8ec4c","optional":false}],"indices":[]},
"dca3ba43188095fa": {"kind":"union","types":["0203243b72fc867a","022623b9ef98ec47","02b2c23f2d94b028","0ed8d1108fe7a5e1","0eeb17e1df89b1eb","11638dc58a31496f","1938c8c20f1cba7c","1e709346005826eb","1fdad624334d3548","2152caf1a71e588e","2235d957bf4b7c6c","224aa11d4d5f88c4","24ce31aa528272e5","260523b412c19ad8","28936c614bd4e7e2","290f32bfd81ff85a","297fbd8067d7815a","2aad1179f9576314","312aee2f0c42aabb","31907de956375182","3247e566f4340029","3b04790e08b35241","3b4f2c9ef2c1217e","3bdb8dc6989655b0","408927267422a7b2","45f005e6bbb76452","4991dfc415c9efeb","49dab019d00e8c26","4a9bef9f27a94252","52c6113cb0e53f34","53cf1704ae0709c7","5654685d7557ec74","58015da1c1950a66","5bb69b88517f6214","5bc66269cfaf614c","5cdbf342b7748d15","5d7a64ed6aac5551","6085488d223aeffd","6292bcbedaa97fea","65a8400e451e667e","65d583e66518c523","672c4aa2a9b736e3","6ccb6bc423fb3952","6ea608bdc8a7a63d","6f22a9d02b9a1f11","6f44f32be9bcd9a8","719c51f67074f970","7554565be416b034","756b5e23a5cb2c7f","7df62978a2b7de85","7eaef7a763ba5b94","7f959241c24128b4","80677c8c8b804189","825ca23416b1ea9d","8338ee303e2bd448","848639f8787f035b","854db3efdfb0cd39","85fe96bf15d5c755","8620189c8e335827","87b1a33564b9a4d6","88841202942c7683","8a046b52331959aa","8c1c4f72755a78ea","8c627d7a45fa406c","8f1062573ea91841","8f324cea3916c051","8fcb0b44a575e998","96bfb916a727cd44","99135d8a39379779","99f0e98184709ad1","9edc162949abf93b","9f65c43e340bba31","a15a19ef63cf5d1b","a16e567c8cd2c55c","a2066bd52f61218b","a3c6f1ea38e9a61d","a4afec59b75aad5d","aa2bf9e82b9fdeb9","aae343bc3d663c83","ada310bf0bdb8fed","ade057f4fdc387ae","b062078e899958f9","b2a5c8c008a31e3d","b3681c026a0b98e9","b4ec0af39fd52ed9","b613f83572fe2fbf","b6f94c17dd9bbd7c","b70f3e81fe11b7a5","b79641a9d25e7566","ba2a1a8f194b1bb2","ba4c40b4381e0dcd","baccc97ec34be6c4","c5228b7a55498d84","c55827fba7018198","cb1c8959e1726f82","cda2345a9be9d139","d85590a5675c6e2f","d9c462b9f62fdd3e","db06ef35b27a3842","dba54c09c6e7aafc","dd00cdccd0ba487b","dd5ee8762bd8a14b","dd6cc2bb2a8f2824","dde0cdf9d426768b","deaae5cd30987d4f","e7f4cbb3a57f4cbd","edbbfff1128099fd","ee577a0cc18664c9","f230c0b583e23b25","f29d63336e8266d8","f4a66f654996c093","f56c5b59ca016131","f6329fb30c7ea801","f6605d6c57933aea","f6afe41e3926f422","f7283223aacdc39b","f97f47b0eb87905e","fcf81d3c58c13593","fe1a7acdeed4d0f5"]},
"dd00cdccd0ba487b": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"dd5ee8762bd8a14b": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"dd6cc2bb2a8f2824": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"dde0cdf9d426768b": {"kind":"object","properties":[{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"de25352d2dc41963": {"kind":"literal","value":"user/message"},
"de30b1fa12c75f81": {"kind":"literal","value":"image/gif"},
"deaae5cd30987d4f": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false}],"indices":[]},
"deebfc7c62177ea8": {"kind":"object","properties":[{"name":"kind","type":"95a3ffccbf3c8afc","optional":false}],"indices":[]},
"df843efd87c78cf8": {"kind":"array","element":"4f91f187baeabef5"},
"e438a9d4fb883b3e": {"kind":"literal","value":"append"},
"e7f4cbb3a57f4cbd": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"e8de0f457fed5b9f": {"kind":"literal","value":"notice"},
"ebb768d85ec87fb6": {"kind":"literal","value":"image/webp"},
"edbbfff1128099fd": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"ee577a0cc18664c9": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"f19bee84bf3d2090": {"kind":"object","properties":[{"name":"attachmentId","type":"4cd48f3e5108bd6e","optional":false},{"name":"bytes","type":"0657d3ca5ac4e7bf","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"f230c0b583e23b25": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"f29d63336e8266d8": {"kind":"object","properties":[{"name":"kind","type":"d9edf1862e4471d6","optional":false}],"indices":[]},
"f2da0f27c1e6add5": {"kind":"object","properties":[{"name":"attachment","type":"f19bee84bf3d2090","optional":false},{"name":"type","type":"277b61f9c6f81704","optional":false}],"indices":[]},
"f4a66f654996c093": {"kind":"object","properties":[{"name":"kind","type":"0fe52387f6505270","optional":false}],"indices":[]},
"f56c5b59ca016131": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"7f13860ee89a2d35","optional":false},{"name":"references","type":"df843efd87c78cf8","optional":false},{"name":"version","type":"f88f1b7b6bb733f6","optional":false}],"indices":[]},
"f6329fb30c7ea801": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false}],"indices":[]},
"f6605d6c57933aea": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"9ac52f0f84fec2eb","optional":false}],"indices":[]},
"f68c335306535a00": {"kind":"literal","value":"user-approval"},
"f6afe41e3926f422": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
"f6cb462f808309e3": {"kind":"literal","value":"replace"},
"f7283223aacdc39b": {"kind":"object","properties":[{"name":"kind","type":"9ac52f0f84fec2eb","optional":false}],"indices":[]},
"f7752f518bb2f916": {"kind":"object","properties":[{"name":"inserted","type":"8a54d228b1b7d845","optional":false},{"name":"outcome","type":"d4e4d575abeb4b72","optional":true},{"name":"removedCount","type":"0657d3ca5ac4e7bf","optional":true},{"name":"start","type":"0657d3ca5ac4e7bf","optional":false},{"name":"target","type":"96f4a9c81fc0f940","optional":false}],"indices":[]},
"f88f1b7b6bb733f6": {"kind":"literal","value":1},
"f97f47b0eb87905e": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"78a9be340090b735","optional":false}],"indices":[]},
"fa87537f4a9c1e25": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"95c0e88fcf0bafb2","optional":false},{"name":"source","type":"719c51f67074f970","optional":false}],"indices":[]},
"fb8b6a2e53cb9cf4": {"kind":"literal","value":"image"},
"fbd2c74b346a1595": {"kind":"literal","value":"agent-instructions"},
"fcf427290c6213c2": {"kind":"primitive","type":"never"},
"fcf81d3c58c13593": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"78a9be340090b735","optional":false}],"indices":[]},
"fe1a7acdeed4d0f5": {"kind":"object","properties":[{"name":"form","type":"e8de0f457fed5b9f","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false},{"name":"summary","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"fee1caf8ab6a65c1": {"kind":"literal","value":"instructions"}
}
}
@@ -0,0 +1,60 @@
---
description: "记录持久化类型更改及其兼容性确认。"
kind: persistence-change
---
# 2026-10-27-retry-control-input
[English](2026-10-27-retry-control-input.md) | 中文
## 概述
为空 Session API 继续提示词增加 retry 消息来源;普通 user/message 记录保留输入身份和调用方元数据。
## 目录
- [声明](#declaration)
- [兼容性](#compatibility)
- [验证](#verification)
- [开发备注](#dev-note)
<a id="declaration"></a>
## 声明
```yaml persistence-change
schemaVersion: 1
id: 2026-10-27-retry-control-input
baseline: false
changes:
- root: "event:agent/inbox/spliced"
previous: "2026-10-27-subagent-settlement-attribution"
after: "1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85"
decision: same-version
- root: "event:developer/message"
previous: "2026-10-27-subagent-settlement-attribution"
after: "510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99"
decision: same-version
- root: "event:session/title-llm-request"
previous: "2026-10-27-subagent-settlement-attribution"
after: "3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18"
decision: same-version
- root: "event:user/message"
previous: "2026-10-27-subagent-settlement-attribution"
after: "50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97"
decision: same-version
```
<a id="compatibility"></a>
## 兼容性
retry 来源是现有空 UserMessage 表示中的生产方元数据。AgentLoop、模型历史派生与 SDK 提示词行为保持不变。旧读取方保留可扩展来源元数据,并按普通用户消息准入消费;旧界面可能显示空上下文行。更新后的读取方保留历史普通消息,Chat 仅隐藏空重试消息。现有事件判别标签与当前 Session 版本不变,不新增必读事件。
<a id="verification"></a>
## 验证
Session API 测试通过:51 个文件、1112 个测试,continuation.ts 的语句、分支、函数和行覆盖率均为 100%。Chat 与 conversation 测试通过:113 个文件、1875 个测试;最终定向 Chat 与输入回归分别通过 96 和 31 个测试。浏览器继续回放通过,断言日志保留空 retry 用户消息、Chat 无空气泡且轮次正常闭合。构建 10 项全部通过,类型感知 lint 退出码为 0,doc-sync 的 43 项全部通过。与 PR 基线的 Git 比较确认 AgentLoop、Core Agent、Core Session 和 SDK 无改动。
<a id="dev-note"></a>
## 开发备注
无。
@@ -15,8 +15,8 @@
en: 14c57f30e676f6e3
zh: b1a0ccf26fab3727
/session-persistence-formats/format-references:
en: 77ac7919d6cac2e4
zh: 1ecb8a42e6d2a0fd
en: 1ebef675a763819c
zh: 19457eb77b815c8c
/session-persistence-formats/scope-and-evidence:
en: b220062139ddac1e
zh: 7c4c0efe05dafa9c
@@ -32,7 +32,7 @@ The index is generated from validated snapshots and the current writer constant.
| 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 | PR #4320 | [V3](v3.md) | [JSON](v3.schema.json) | 60 / 467 |
| 4 | Current checkout | [Current catalog](../../persistence-catalog.md) | [JSON](../../persistence-schema.json) | 66 / 634 |
| 4 | Current checkout | [Current catalog](../../persistence-catalog.md) | [JSON](../../persistence-schema.json) | 66 / 636 |
<!-- persistence-format-index:end -->
@@ -32,7 +32,7 @@ description: "查找从 V0 到工作区写入器版本的每个 Session 格式
| 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 | PR #4320 | [V3](v3.zh.md) | [JSON](v3.schema.json) | 60 / 467 |
| 4 | 当前工作树 | [当前目录](../../persistence-catalog.zh.md) | [JSON](../../persistence-schema.json) | 66 / 634 |
| 4 | 当前工作树 | [当前目录](../../persistence-catalog.zh.md) | [JSON](../../persistence-schema.json) | 66 / 636 |
<!-- persistence-format-index:end -->
+36 -32
View File
@@ -5,7 +5,7 @@
{"key":"JsonlHeaderLine","kind":"header","digest":"18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f"},
{"key":"SessionEventEnvelope","kind":"envelope","digest":"5776e5553ff2dfe3f5bc202dbb1e7c9f93e35a531aebb7764c23b2b6153b2ccc"},
{"key":"event:agent-preset/selected","kind":"event","event":"agent-preset/selected","surface":false,"digest":"a10c17474eaf2ddab7095a099e0fe3d046fc18e56c3e344fc8894c05ff9ef97b"},
{"key":"event:agent/inbox/spliced","kind":"event","event":"agent/inbox/spliced","surface":false,"digest":"ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482"},
{"key":"event:agent/inbox/spliced","kind":"event","event":"agent/inbox/spliced","surface":false,"digest":"1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85"},
{"key":"event:approval/asked","kind":"event","event":"approval/asked","surface":false,"digest":"3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1"},
{"key":"event:approval/decided","kind":"event","event":"approval/decided","surface":false,"digest":"bb1ab3d08f49a9f3b265f844cd78d5c49813062a7b34b54904b426f85d0ff6e3"},
{"key":"event:approval/policy","kind":"event","event":"approval/policy","surface":false,"digest":"26718e15e7e395bce9642dba5bbe09b3b1a4ce2213d20d566cd9207d7fc5fb78"},
@@ -18,7 +18,7 @@
{"key":"event:compaction/start","kind":"event","event":"compaction/start","surface":false,"digest":"db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965"},
{"key":"event:compaction/summary","kind":"event","event":"compaction/summary","surface":false,"digest":"e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602"},
{"key":"event:deliverables/presented","kind":"event","event":"deliverables/presented","surface":false,"digest":"13d3d180f977bf78081d487ffa0ecb75857349bcab29a5a3fb48189fca2a6176"},
{"key":"event:developer/message","kind":"event","event":"developer/message","surface":true,"digest":"70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a"},
{"key":"event:developer/message","kind":"event","event":"developer/message","surface":true,"digest":"510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99"},
{"key":"event:feedback/message-delete","kind":"event","event":"feedback/message-delete","surface":false,"digest":"3ee93b06f3a125850337602bcdf155d2538c43a5c944ec55b1b3c365152d6796"},
{"key":"event:feedback/message-put","kind":"event","event":"feedback/message-put","surface":false,"digest":"b5086d249e8502e9ead1d39156bb8d559bde7951cac0f14ce150345b4e42a2bf"},
{"key":"event:feedback/record","kind":"event","event":"feedback/record","surface":false,"digest":"b54940ff095c17e874c5be03815f4c2145a256cf3a1d34dae4ab2f7769dfffe8"},
@@ -40,7 +40,7 @@
{"key":"event:session-log-deepseek/delivery-accepted","kind":"event","event":"session-log-deepseek/delivery-accepted","surface":false,"digest":"d63b8b8ffad9c02fd80c43a17df4f240c1fe8118ecca9de34f9d5871838ab5b9"},
{"key":"event:session/end-seed","kind":"event","event":"session/end-seed","surface":false,"digest":"5e6db6e24948d4a853c71cb9fabd252ad051ce93d4672c1266cf837c1c17b84e"},
{"key":"event:session/title","kind":"event","event":"session/title","surface":false,"digest":"1b912703e2d64f91c99c675b8f805b01076c8325b905c1218ad81ef0b24909d5"},
{"key":"event:session/title-llm-request","kind":"event","event":"session/title-llm-request","surface":false,"digest":"d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca"},
{"key":"event:session/title-llm-request","kind":"event","event":"session/title-llm-request","surface":false,"digest":"3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18"},
{"key":"event:step/end","kind":"event","event":"step/end","surface":false,"digest":"e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05"},
{"key":"event:step/start","kind":"event","event":"step/start","surface":false,"digest":"4513e088d43e6c68425be30451b9f961cc264fe7318ca62681c41d4d78615986"},
{"key":"event:subagent/catalog","kind":"event","event":"subagent/catalog","surface":false,"digest":"d49164d37eab0f0f70fa787c65d887abbea869c010ccb103d717fab3519c3a41"},
@@ -63,14 +63,13 @@
{"key":"event:tool/result","kind":"event","event":"tool/result","surface":true,"digest":"7c9f44e90a0058f4cc532ae20dad0c10afa6eba22e70a6c79fc79490bad64397"},
{"key":"event:turn/end","kind":"event","event":"turn/end","surface":false,"digest":"0f8512903d94f57a4748fa1a2092e64342856796684e6b8343db685b192745ce"},
{"key":"event:turn/start","kind":"event","event":"turn/start","surface":false,"digest":"aa0957eca50aeb28bcd2e6930b95809926edacb550c8c340ba526ba6b861b3d8"},
{"key":"event:user/message","kind":"event","event":"user/message","surface":true,"digest":"dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450"},
{"key":"event:user/message","kind":"event","event":"user/message","surface":true,"digest":"50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97"},
{"key":"event:web/deepseek-search-llm-request","kind":"event","event":"web/deepseek-search-llm-request","surface":false,"digest":"0c556c9b9f2a96238a6b9bbb99e748206cbff2ed6203041c9571f04ae5802f52"},
{"key":"event:working-directory/change","kind":"event","event":"working-directory/change","surface":false,"digest":"124aa62078ca3311353b39cc3bf6c75da281338be6bbf672f8b361d828cddca3"},
{"key":"event:workspace/changes","kind":"event","event":"workspace/changes","surface":false,"digest":"e308ccf867a5398e316e0af8cb6ce238a8d33a63b9b384c8250a686786285f72"}
],
"types": [
{"digest":"0116b1f89c05221d56b0ba35c83d302bf4857bc7277d247e9bbaf74b27d2c66e","names":[],"sources":[]},
{"digest":"01c161379a3c3394a642807843e108ef911a8b7dbffd6d7de43f4484c88b0796","names":["packages/llm/llm/src/message.ts#DeveloperMessage"],"sources":["packages/llm/llm/src/message.ts:157"]},
{"digest":"0203243b72fc867afc81aff5f4cf2167e564ed342534eb612fc92f295cf07789","names":[],"sources":[]},
{"digest":"022623b9ef98ec47ec3c3bae0c51027c70d2601141c5e92e26a0d83d1b4cef06","names":[],"sources":[]},
{"digest":"023a355b2be0d688fb6e4df8388dadb942761d46cfe96d0f499aae9631a159d4","names":[],"sources":["packages/core/session/src/types.ts:211"]},
@@ -123,6 +122,7 @@
{"digest":"15495614ccfa9cbdeefb0ec2abd76406435f4c6ff3dae42acae8e09ef42025c9","names":[],"sources":[]},
{"digest":"1571525adc95a24e5d25b5a6440df401cd7cdd881b745178e85f5a333435cd1b","names":[],"sources":[]},
{"digest":"15d5dfdd822aa35e115afd74a8982825a493880457774e6850bc1520b50875e4","names":[],"sources":[]},
{"digest":"1682631f010d5ea717d181ed6f4ef46cde08d92a31ab461e7e98edfc98461f85","names":[],"sources":[]},
{"digest":"16d0507cb94b4cfc84a87446b1ba7652d6ec1d65ee1684789e747e30d542800e","names":[],"sources":[]},
{"digest":"17aae616ef020b8b9f011ec398ec935450fb06d3e2a0722c456f63aeaf5ff728","names":[],"sources":[]},
{"digest":"17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3","names":[],"sources":["packages/core/session/src/types.ts:435"]},
@@ -176,6 +176,7 @@
{"digest":"287211846beea1eccb5f9acee00d20388a38fcb2e95858fa2332d6f58529379a","names":[],"sources":["packages/llm/llm/src/types.ts:165"]},
{"digest":"28936c614bd4e7e2774806edcbb3cbfd3ee643ac1cbf0bbdff43d915505a8fe3","names":[],"sources":[]},
{"digest":"290f32bfd81ff85a8095886a8066fae06e885942b63a8bcd6a8d66d328445808","names":[],"sources":[]},
{"digest":"295809283ede248d14e6a431dec1c464cfd80a54b0d8f2a5994219fd8c8f9998","names":[],"sources":["packages/core/session/src/types.ts:317"]},
{"digest":"297fbd8067d7815adae02b89790ec6ff5fb7c2cb0d0eb026e1746c24ec857761","names":[],"sources":[]},
{"digest":"2aad1179f957631477b582e57cd8f538cb82618fc3fb816bde1171154235b065","names":[],"sources":[]},
{"digest":"2ab12a0e345658f9342816d773fe610f049982bcad82631f43b9205abe43e5ee","names":[],"sources":[]},
@@ -216,6 +217,7 @@
{"digest":"3b1be838223869fe0a08210db85bf773796ed3f2373ac16555dff227cade0c48","names":[],"sources":[]},
{"digest":"3b4f2c9ef2c1217eac596c7b070173cb7896e2fae09e729bc7c56c801e56bb29","names":[],"sources":[]},
{"digest":"3bc287e765d58dc3a22672a0495a6cfd561220dd38fbaecef80aa95b96caed79","names":[],"sources":[]},
{"digest":"3bca25b2baa6b22be9b577621a7603497f40870ed88a8dac4383d37dc2bb6e18","names":[],"sources":[]},
{"digest":"3bd652ebfa8726b3ce3937a4f1bd2759e02f86b3a08a20f9e41a8513656fbc5f","names":["packages/core/session/src/types.ts#OptionalSessionSeq"],"sources":["packages/core/session/src/types.ts:66"]},
{"digest":"3bdb8dc6989655b0d4ec361edafb8e2629bc263e1ea591819414fdafc1a413b3","names":[],"sources":[]},
{"digest":"3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90","names":[],"sources":["packages/llm/llm/src/types.ts:497"]},
@@ -233,6 +235,7 @@
{"digest":"408927267422a7b2beb6df354ff7c1406d929a5646554f48adf85eb8372f811c","names":[],"sources":[]},
{"digest":"4208123b50df5006b181481ab45fcf1cde807b88d3fd4d340090bc2e202fac41","names":[],"sources":[]},
{"digest":"42e0916e0dda5f6d1e7bb05d8514717147c036a79c9f36085683469516c1fd3f","names":[],"sources":[]},
{"digest":"42e2ff61928fb7dfaf0f057d61686f3a32ff713da419d12d4f250efc96733fe0","names":[],"sources":[]},
{"digest":"4312134fc6f9cad507c31390bd3d147535492dd77621ec517c5e85f853d53a03","names":[],"sources":[]},
{"digest":"43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8","names":["packages/llm/llm/src/types.ts#ToolRemovalBlock"],"sources":["packages/llm/llm/src/types.ts:134"]},
{"digest":"44818000e56acb97afdb5045ce235eb55e3fb1ccabc9fc7d0750bb38f36a7f8e","names":[],"sources":[]},
@@ -256,7 +259,7 @@
{"digest":"4b259f7f8f0a44ad5e90b70a73553ced1df27012d126921d397ff403b6c86731","names":["packages/llm/llm/src/message.ts#ToolResultMessage"],"sources":["packages/llm/llm/src/message.ts:173"]},
{"digest":"4b7ddaf3710b88ff9b8df66304f5f97bf03688fd19730eedc2e9535203c820ea","names":[],"sources":[]},
{"digest":"4bb451330ff699f36b45539ceb0eb2606ead72084e2c5bb637c36cc80e2252db","names":[],"sources":["packages/core/session/src/types.ts:198"]},
{"digest":"4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b","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/webhook/src/brand.ts#WebhookDeliveryId","packages/experimental/webhook/src/brand.ts#WebhookRuleId","packages/experimental/webhook/src/brand.ts#WebhookSourceId","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/jobs/jobs/src/brand.ts#JobId","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/team/agent-team/src/types.ts#TeamId","packages/team/agent-team/src/types.ts#TeamMessageId","packages/team/agent-team/src/types.ts#TeamTaskId","packages/workflow/workflow/src/types.ts#WorkflowRunId"],"sources":["packages/api/session-controller/src/types.ts:389","packages/attachment/attachment/src/brand.ts:6","packages/compaction/compaction/src/brand.ts:4","packages/core/session/src/types.ts:21","packages/experimental/webhook/src/brand.ts:12","packages/experimental/webhook/src/brand.ts:6","packages/experimental/webhook/src/brand.ts:9","packages/feedback/message-feedback/src/types.ts:14","packages/goal/goal/src/types.ts:17","packages/interaction/commands/src/brand.ts:31","packages/interaction/user-approval/src/types.ts:17","packages/jobs/jobs/src/brand.ts:19","packages/llm/llm-retry/src/brand.ts:4","packages/llm/llm/src/brand.ts:16","packages/llm/llm/src/brand.ts:31","packages/llm/llm/src/brand.ts:43","packages/llm/llm/src/brand.ts:67","packages/schedule/schedule/src/types.ts:14","packages/session/session-title/src/index.ts:42","packages/session/session-title/src/types.ts:17","packages/team/agent-team/src/types.ts:20","packages/team/agent-team/src/types.ts:32","packages/team/agent-team/src/types.ts:8","packages/workflow/workflow/src/types.ts:13"]},
{"digest":"4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b","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/webhook/src/brand.ts#WebhookDeliveryId","packages/experimental/webhook/src/brand.ts#WebhookRuleId","packages/experimental/webhook/src/brand.ts#WebhookSourceId","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/jobs/jobs/src/brand.ts#JobId","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/team/agent-team/src/types.ts#TeamId","packages/team/agent-team/src/types.ts#TeamMessageId","packages/team/agent-team/src/types.ts#TeamTaskId","packages/workflow/workflow/src/types.ts#WorkflowRunId"],"sources":["packages/api/session-controller/src/types.ts:391","packages/attachment/attachment/src/brand.ts:6","packages/compaction/compaction/src/brand.ts:4","packages/core/session/src/types.ts:21","packages/experimental/webhook/src/brand.ts:12","packages/experimental/webhook/src/brand.ts:6","packages/experimental/webhook/src/brand.ts:9","packages/feedback/message-feedback/src/types.ts:14","packages/goal/goal/src/types.ts:17","packages/interaction/commands/src/brand.ts:31","packages/interaction/user-approval/src/types.ts:17","packages/jobs/jobs/src/brand.ts:19","packages/llm/llm-retry/src/brand.ts:4","packages/llm/llm/src/brand.ts:16","packages/llm/llm/src/brand.ts:31","packages/llm/llm/src/brand.ts:43","packages/llm/llm/src/brand.ts:67","packages/schedule/schedule/src/types.ts:14","packages/session/session-title/src/index.ts:42","packages/session/session-title/src/types.ts:17","packages/team/agent-team/src/types.ts:20","packages/team/agent-team/src/types.ts:32","packages/team/agent-team/src/types.ts:8","packages/workflow/workflow/src/types.ts:13"]},
{"digest":"4d60dddaa65d3da8d4cd014d85ce3d2c2875664dd0433e331d8e9d395289686b","names":["packages/experimental/liveshare/src/host/viewer-principal.ts#ShareViewerPrincipal"],"sources":["packages/experimental/liveshare/src/host/viewer-principal.ts:24"]},
{"digest":"4e011753f8263f436efaabfbb3b4db53a98fc55342c5ded2daf7208b217be159","names":[],"sources":[]},
{"digest":"4e44c9118152f6829634bfd508e47669ab0497caffa380c94b4be91f9390d35d","names":[],"sources":[]},
@@ -265,7 +268,9 @@
{"digest":"4f507598cf476214aa7646ce7841a7064a9dcb05d0a1eaaefaf79c2b738f160f","names":[],"sources":[]},
{"digest":"4f91f187baeabef5c7950c4780d31bbe39f3345dff591a6cf26ac7e135ac1cf4","names":[],"sources":["packages/context/session-reference/src/types.ts:18"]},
{"digest":"4fb59762612c3e3ac3a3bd4f84c9c148d3c3893bd422ba2b201cc039fabd49bc","names":[],"sources":[]},
{"digest":"50a15408d511e9be3fa93abff37a38ae770f3ab905fc6849fee0d989200d2b97","names":[],"sources":[]},
{"digest":"50cf02d875f8a1f1411f4a6fbcffab9120ccef5f74a47331fbf29480e5f68f48","names":[],"sources":[]},
{"digest":"510826cf4e1f9220d75c1efd90b349dd9a77fc5ba15d19e16f87e85a48db5f99","names":[],"sources":[]},
{"digest":"511801b0a6470d98566e8385d3dffddb2b67f79fcf73ed6056f46c3cc0a245a7","names":[],"sources":[]},
{"digest":"516da4cdd6d2f1e5ce488e648578ca51f40e458f707b803e5b24de870e799415","names":[],"sources":[]},
{"digest":"525254db03b1d1e6b74cf55aced52817568331ac1f96c0818728910b6692e336","names":[],"sources":[]},
@@ -306,17 +311,15 @@
{"digest":"5f2117d1856a5ab43c28371faa978ebfaa48f8c7d734ea3fc94842210df83dca","names":["packages/llm/llm/src/types.ts#LlmFailure"],"sources":["packages/llm/llm/src/types.ts:48"]},
{"digest":"5f26a6c20b37632f8f57729d171c671def4683d994ac6257a8dffcd855101627","names":[],"sources":[]},
{"digest":"5f758f3de5f00c18968a7c6d347083aac5c9ae13f6a79c78f6611b23c4973564","names":["packages/subagent/subagent/src/descriptor.ts#OneShotSubagentDescriptorData"],"sources":["packages/subagent/subagent/src/descriptor.ts:61"]},
{"digest":"601327bedca5f98a0fa4c27133bd35749f3af2baaaacf53badf074e59cea5d25","names":["packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData"],"sources":["packages/session/session-title-llm/src/index.ts:43"]},
{"digest":"6085488d223aeffdef51d7ae17655fc26ab22ee13cbed82a50e62e2b6fb5b918","names":[],"sources":[]},
{"digest":"611cae9a3539733aa0c42f66035a7d90f19dcbbdfb5d9e3b628b13705253942d","names":[],"sources":[]},
{"digest":"611d82d2dc50df706cf08a0fc04bc8eaf78083391fe6f10313de943e615dd2da","names":["packages/jobs/jobs/src/types.ts#JobSettledData"],"sources":["packages/jobs/jobs/src/types.ts:40"]},
{"digest":"613660455704fb82a825b5b766e000aa64b5b4d44b4f10e55cffe968d4ec6ab1","names":["packages/llm/llm/src/message.ts#UserMessage"],"sources":["packages/llm/llm/src/message.ts:162"]},
{"digest":"616f93a5047de668e1c30d57b1786abd76beeb4123599637ec1dc5290320ede5","names":[],"sources":[]},
{"digest":"6292bcbedaa97feaec5b48a03bb8144b581b93309d9d6c905f26da7a6a7a0a4f","names":[],"sources":[]},
{"digest":"62e6a429ff3f390a46ac39fb468692032f42936ca0db19b53454184189401379","names":[],"sources":[]},
{"digest":"62ecb62dc0fe1b5e70217f8a80c39256a40ee3a1917be14e5ca899d20c35f7fd","names":[],"sources":[]},
{"digest":"63ba8895cc09e4693cf0819fdcd18c084bef195febda5b6a23af279b3852be36","names":[],"sources":[]},
{"digest":"6487b10ba7542f3c447b1e41a1c6a590b7bfafe0b9b66b49f34028da85bb970f","names":["packages/subagent/subagent/src/descriptor.ts#ContinuableSubagentDescriptorData"],"sources":["packages/subagent/subagent/src/descriptor.ts:72"]},
{"digest":"65377a76c6a58f785d95b89f89f2e13d289cb88a70ea74939d0ec08f429f0a6e","names":[],"sources":["packages/core/session/src/types.ts:317"]},
{"digest":"6598cd6da253948d6b207c6374a45335804c79b576866d6215649c2d1bc85e25","names":["packages/team/agent-team/src/types.ts#TeamMemberSnapshot"],"sources":["packages/team/agent-team/src/types.ts:50"]},
{"digest":"65a8400e451e667e5b6e34df72ceb81fca8c12330330fa72083ad40279b189ad","names":["packages/llm/llm/src/message.ts#SystemPromptMessageSource"],"sources":["packages/llm/llm/src/message.ts:35"]},
{"digest":"65d583e66518c5236015e0846470fb32efcf92375ed306aef14e50a9d2cd2099","names":["packages/skill/tool-skill/src/index.ts#SkillCatalogSource"],"sources":["packages/skill/tool-skill/src/index.ts:35"]},
@@ -326,7 +329,6 @@
{"digest":"68141cbe3994a5ffcd064c07c75996538437fd9dbf77ce8a2927e89ec577fabe","names":[],"sources":[]},
{"digest":"688e853dc149f0d30b31765c12ec7e3be74169bdf1a4c6463a10b945d50cc1b8","names":[],"sources":[]},
{"digest":"68f44f59e91c41395076cb77265981a601680ec8a381bbbeb6ab754ffdc94573","names":[],"sources":[]},
{"digest":"690583582246babf6120f16eefd849dd760c5ec84619014951af403a1b3032c0","names":[],"sources":[]},
{"digest":"69081694be231d56fd9580ba14645fd5e35373202605d5c5c841a9435b5fa3b1","names":[],"sources":[]},
{"digest":"693f4952fb5565da96c06bace8924b098ac2fbc915fde0ff8019701183abc057","names":[],"sources":["packages/llm/llm/src/types.ts:168"]},
{"digest":"69d238a6e9b08d67f601b1825962963d8d3523cb69ebf6208c697dc5d058c199","names":[],"sources":[]},
@@ -351,12 +353,12 @@
{"digest":"6f72ece8f317cd080c4f20a93f1bf709965f5b81ac4669528f5a023191cfcf20","names":["packages/llm/llm-retry/src/types.ts#LlmRetryStartedEventData"],"sources":["packages/llm/llm-retry/src/types.ts:43"]},
{"digest":"6f9e00383836275e46c0a9915767f9bb561be5fc30aae490174908a93e99a912","names":[],"sources":[]},
{"digest":"70b082fe78991edf13cf66e1b4d06cd2dcff9cacfd76f8cfb996bfb61939e7b2","names":[],"sources":[]},
{"digest":"70ea8e7943c5e2d76905bcc2e694e8c3d5b138aaae3609f3e261b8d369a6e35a","names":[],"sources":[]},
{"digest":"7180844e1066230c5e891f1b9ccd942423b0fe48aac6ded7eef2a285b288a732","names":[],"sources":[]},
{"digest":"719c51f67074f97034a6c94297fe1f4b5d3c8d392c57586dab732aa5398c7a91","names":["packages/llm/llm/src/message.ts#ModelMessageSource"],"sources":["packages/llm/llm/src/message.ts:24"]},
{"digest":"71bb3254ec8f1e491ce63b762a7b5f18709de23aa4e8abcc8b886f4b6ce051dd","names":[],"sources":["packages/llm/llm/src/assistant-stream.ts:28"]},
{"digest":"72ec79127a9c0d0241b1106a74cc2b24c81ce467170f1c3c93f7b71a9496d227","names":[],"sources":[]},
{"digest":"7382c4fc95fe8c5db65ca4d9da572b115d0dbb818b7f32c22ab040318ffbb4bc","names":[],"sources":[]},
{"digest":"74e0e5885d2ddf04530ddf341b25cd65e1f85c00b30a88bd992f11fc06615a0c","names":["packages/llm/llm/src/message.ts#UserMessage"],"sources":["packages/llm/llm/src/message.ts:162"]},
{"digest":"750a2b129d67704df675c06823c20c80b65cbae89d5aaa914fd5a72e3df395b5","names":["packages/jobs/jobs/src/types.ts#JobSettleCause"],"sources":["packages/jobs/jobs/src/types.ts:247"]},
{"digest":"7554565be416b0342053ee6a46256c9dab07c487349b4a5f10bab1edc151c619","names":[],"sources":[]},
{"digest":"756b5e23a5cb2c7f486f366a828f7461c88902af21125bd6810881f4ccbff6cc","names":[],"sources":[]},
@@ -387,6 +389,7 @@
{"digest":"814d9434e1ddf9078612b3b34322f26e9363b469213335007f7e9ba7fee9464e","names":["packages/llm/llm/src/types.ts#ReasoningBlock"],"sources":["packages/llm/llm/src/types.ts:75"]},
{"digest":"82470020b5bfcb1a843e2aa05602af7d37df99e82d01f015c7c589ba054fd89d","names":[],"sources":[]},
{"digest":"824a4aad44a54e245c67196817d67946734a2dc0eee0b0b6834a5b2a6ef352ce","names":[],"sources":[]},
{"digest":"824b1d4d4f007bdaa5eee7994a5db3ede7707c6cd2bf8e2509be176c7609e3bc","names":["packages/llm/llm/src/message.ts#DeveloperMessage"],"sources":["packages/llm/llm/src/message.ts:157"]},
{"digest":"825ca23416b1ea9d81442afead5cf9229a6fa05842f042135cc3aa9710a6a2d8","names":[],"sources":[]},
{"digest":"829a2fb3be6efd4ba36aef8ed2d381a4c6fb2a0aaf50c823a6f3f8290786b809","names":[],"sources":[]},
{"digest":"83079c8a3f733ac3fa603eefa0fbb4737ca4d8b69e7e2e7298b60f9ac4098693","names":[],"sources":["packages/skill/tool-skill/src/index.ts:43"]},
@@ -410,6 +413,7 @@
{"digest":"88841202942c7683b3b7e5ea6a796047ec326b6701ac23e58cc236d85613b9fa","names":[],"sources":[]},
{"digest":"88a610b831be6d92612a464be5c7d0b88ec24d97bd299837bf74bf7672183c9a","names":[],"sources":["packages/llm/llm/src/types.ts:500"]},
{"digest":"8a046b52331959aa3394680d6acbe09b8a5447c6b61375f263445bfcef19b7f1","names":[],"sources":[]},
{"digest":"8a54d228b1b7d8453e4304d32723d489f28b4b33b221f335342146926ad94fc6","names":[],"sources":[]},
{"digest":"8a6e1ec9e8db346b0e02f027db73c07a94f067a26d40c1aef1abd09c47ce7ba0","names":[],"sources":[]},
{"digest":"8a9c990773f798eac10ca8878e6bcc531ee080bc589cac956730e462cc6a09ad","names":[],"sources":["packages/interaction/permission-presets/src/index.ts:53"]},
{"digest":"8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141","names":[],"sources":["packages/experimental/hook-protocol/src/types.ts:31"]},
@@ -422,6 +426,7 @@
{"digest":"8e611bf46821e5003a1605a73560a6f56388295149d449dfe2142d5ec335f29c","names":["packages/llm/llm/src/types.ts#ToolAdditionBlock"],"sources":["packages/llm/llm/src/types.ts:122"]},
{"digest":"8e8155594e07812356b67d732196dda894b0f9c91a5969d51612cf490b0a016d","names":[],"sources":[]},
{"digest":"8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af","names":["packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange"],"sources":["packages/schedule/schedule/src/types.ts:213"]},
{"digest":"8f1062573ea9184129dfdec43df1e8136eb5808746fd809bf6b539f3fd11362e","names":[],"sources":["packages/api/session-controller/src/types.ts:402"]},
{"digest":"8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4","names":[],"sources":[]},
{"digest":"8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9","names":[],"sources":[]},
{"digest":"8faed5b52ab2d2df40b94a926d0f0faa75280bddcc4b17b6bdd9c8bfed7c34b5","names":[],"sources":[]},
@@ -437,7 +442,6 @@
{"digest":"94c56aeb1564ad735eb773d88636b40761d063efa1610f1308004d32923f5378","names":[],"sources":[]},
{"digest":"95080295115fbd83544520ba247b68a03790131f6a2eac323d388758cb542f65","names":[],"sources":["packages/llm/llm/src/types.ts:498"]},
{"digest":"95a3ffccbf3c8afcf9a2f3b355f724da8e07e98dc47ee741166dde7f9ea058bd","names":[],"sources":[]},
{"digest":"95b5cf90ea1f57da3319184d6f5f3811d0f651aa9113591c10e81c3d1e9b9f70","names":[],"sources":[]},
{"digest":"95c0e88fcf0bafb2087f912ad9e2369de6ae6530cc0c4c2772c96205b57f7f60","names":[],"sources":[]},
{"digest":"9645cf93769a6dfb227bd400bd6cb9fa7bab9140f4a851e4ae92514ade6e3114","names":[],"sources":[]},
{"digest":"96bfb916a727cd4445a594df264c523fc039749a31bfed924b8cc7bb308a5bb0","names":[],"sources":[]},
@@ -476,7 +480,7 @@
{"digest":"a3c6f1ea38e9a61d7a9706057ba65aabe02dfe6d9dd90d4736aa62325d874531","names":[],"sources":[]},
{"digest":"a3edd1efd1fef21b72c55e213c8a8b24196b091abde2b89db52be0b2aaae3cfa","names":[],"sources":[]},
{"digest":"a43327a1739c3fa477f32981071fef7d8ba6ae5f32a84fd70f547b2eee59e93e","names":[],"sources":[]},
{"digest":"a4afec59b75aad5d13ef82d6931f35cc2d98918503916cf069355b77c5e42302","names":[],"sources":["packages/api/session-controller/src/types.ts:398"]},
{"digest":"a4afec59b75aad5d13ef82d6931f35cc2d98918503916cf069355b77c5e42302","names":[],"sources":["packages/api/session-controller/src/types.ts:400"]},
{"digest":"a6567ccb2e530606b775371eb4fa31468d72084339968e8b0440a516a23b39dc","names":[],"sources":[]},
{"digest":"a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb","names":["packages/experimental/hook-protocol/src/types.ts#HookDialect"],"sources":["packages/experimental/hook-protocol/src/types.ts:48"]},
{"digest":"a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c","names":["packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData"],"sources":["packages/workflow/tool-workflow/src/types.ts:14"]},
@@ -513,7 +517,6 @@
{"digest":"b0127044ab31a702bddfd785d345f5abd7a70876746e895ce443afa3e60ddf2d","names":[],"sources":[]},
{"digest":"b062078e899958f99ae464514578b8c093924dfe34bd9a835932b420ff2150b1","names":[],"sources":[]},
{"digest":"b0b0eb1b16490f6bee135b2377e8f8c39227974c799ad7d49ff418af23ecbc35","names":["packages/attachment/attachment/src/types.ts#ImageAttachmentRef"],"sources":["packages/attachment/attachment/src/types.ts:11"]},
{"digest":"b120362fd216a16a40fe787f6d3286086aa131266322bab79c026a130ccd0f72","names":["packages/llm/llm/src/message.ts#MessageSource"],"sources":["packages/llm/llm/src/message.ts:136"]},
{"digest":"b158f3ff6923714807c0d73882f0b05dc87f8fa85c9e90814852d48bbc866081","names":["packages/core/session/src/types.ts#RequestContext"],"sources":["packages/core/session/src/types.ts:260"]},
{"digest":"b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7","names":[],"sources":[]},
{"digest":"b1ebd5cda47d90d980bb05bffc3f970c51537b9aff15b3bc3d639811727741b1","names":[],"sources":["packages/team/agent-team/src/types.ts:179"]},
@@ -559,6 +562,7 @@
{"digest":"bca0f9cb63d8620b6954bb045b07bb07cb557513a7f0e2e177f5e87f704e7ba7","names":[],"sources":[]},
{"digest":"bcf0caf62d964b2fcf5404bd5c909cfa9a21c3f3c96e6b7e36d9e33565223825","names":[],"sources":["packages/core/session/src/types.ts:472"]},
{"digest":"bd499eac047efe091a4df7382eadd06d25cf0cb31fee3981e8b24d85762841cd","names":[],"sources":[]},
{"digest":"bec5ca3a376f56f3d69df7f12a48e1cc07d4ea8305968773394c8734799faeb4","names":["packages/session/session-title-llm/src/index.ts#SessionTitleLlmRequestEventData"],"sources":["packages/session/session-title-llm/src/index.ts:43"]},
{"digest":"bf16d2e98a7f13894ded2cffe5ce857bf473954a0e3c0ed9bc7739e2e1c7b78a","names":[],"sources":[]},
{"digest":"c0ea97bc89dfc46fa94eab956f5c3ee6af2f964aa7db6327cb18b451f207bef7","names":["packages/workflow/tool-workflow/src/types.ts#ToolWorkflowAgentEndData"],"sources":["packages/workflow/tool-workflow/src/types.ts:29"]},
{"digest":"c170da8ab7c37635b10867b2571811d9e317ac3ec394e8ff8efe53f902fc41c1","names":["packages/llm/llm-retry/src/types.ts#LlmRetryEventData"],"sources":["packages/llm/llm-retry/src/types.ts:16"]},
@@ -569,6 +573,7 @@
{"digest":"c2deb7c9183735d4e0fffddf5c623f4e34daa1c8e96b111982e957dfcbbcf896","names":["packages/workflow/workflow/src/types.ts#WorkflowAgentOutcome"],"sources":["packages/workflow/workflow/src/types.ts:110"]},
{"digest":"c2f49004d9ae38a964e80850c87bc6849d6a872091a1d43e99eedf00c641e2a3","names":[],"sources":[]},
{"digest":"c43b119ce579b3e9983a0d3adc4ba402ebb9ba773d89738a2dab01ecf5813943","names":[],"sources":[]},
{"digest":"c51f0d0a405bb96fcb008c0dc560a512dcd8c3919b6b446937f449ea2f7d21d8","names":["packages/llm/llm/src/message.ts#Message"],"sources":["packages/llm/llm/src/message.ts:196"]},
{"digest":"c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49","names":[],"sources":[]},
{"digest":"c55827fba7018198772c50e37cb7d3f60a3d8bb6e94b07de72dee0d9f8968005","names":[],"sources":["packages/interaction/user-questions/src/types.ts:134"]},
{"digest":"c5687b1313206a6ff334066047b6a0681611467dc4df8c5a8e71d0b6df39311f","names":[],"sources":[]},
@@ -600,7 +605,6 @@
{"digest":"d85590a5675c6e2fd8164e5792a6cceac714605b8ac228adae5ee668facb1490","names":[],"sources":[]},
{"digest":"d8a476d2c6fd30df6ec0e799f91716d1518c780d23b4121dce545abfcfb7c5a5","names":[],"sources":[]},
{"digest":"d9196086e41e4dd5c2ce87f5c25529c8112a1731d258cf0728747d41a9ee3241","names":[],"sources":[]},
{"digest":"d95c624eddecdacf1ee74356196c09d2f3fcd625714be5e852a6b643fa12a7ca","names":[],"sources":[]},
{"digest":"d9c462b9f62fdd3efc76a44b9524dc8781f6b91cd9c7e584b17d971defafebab","names":["packages/llm/llm/src/message.ts#ToolMessageSource"],"sources":["packages/llm/llm/src/message.ts:29"]},
{"digest":"d9edf1862e4471d6ad8a106a3f4160e0643874368707d50ecd8e27e5ee7a2567","names":[],"sources":[]},
{"digest":"da60ed58a8fa23d7aa4920ab5c1f4e3d28109cb0797ef9e5c8b125721b847582","names":[],"sources":["packages/session/working-directory/src/index.ts:36"]},
@@ -610,12 +614,11 @@
{"digest":"db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965","names":[],"sources":[]},
{"digest":"dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd","names":[],"sources":["packages/core/tool-executor-ptc/src/types.ts:68"]},
{"digest":"dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc","names":[],"sources":[]},
{"digest":"dcb07e04496586d2664d72dab0e94312917da56927b2a0dc3ee53d6a33e32450","names":[],"sources":[]},
{"digest":"dca3ba43188095fa7342e49e6c206d4685125497d4767595bf12a62ea2fd73ce","names":["packages/llm/llm/src/message.ts#MessageSource"],"sources":["packages/llm/llm/src/message.ts:136"]},
{"digest":"dd00cdccd0ba487b92362ef67db58cd264f48c1bfd368291424a1da9a899489a","names":[],"sources":[]},
{"digest":"dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d","names":[],"sources":[]},
{"digest":"dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5","names":[],"sources":[]},
{"digest":"dd6cc2bb2a8f28248347021ad93565360b196a042360b4cd16b569d3a2a91f2d","names":[],"sources":[]},
{"digest":"ddce54a3873dc57113b0cd38ad9b23b3c259186139e8847e5e5f415d86f52482","names":[],"sources":[]},
{"digest":"dde0cdf9d426768b649b5a9783d2144e7f900c35ef65229cd89036dbf411d1b0","names":[],"sources":[]},
{"digest":"de25352d2dc4196309bd84b5bac6319f6d5c898ea0e82bb5ae66c5738d0d426f","names":[],"sources":[]},
{"digest":"de30b1fa12c75f81df6aa4096e1595296d2d04e2be14a7c29849cf8028b79048","names":[],"sources":[]},
@@ -625,8 +628,6 @@
{"digest":"df843efd87c78cf8de98f8e0d0216956cd568d0d0e56a22c853663e274aa1a18","names":[],"sources":[]},
{"digest":"dfce5db4aa42b7ebe0bb79eca92553587287e18c06b9eba85cbfb9d332e26acd","names":["packages/team/agent-team/src/types.ts#TeamMemberPhase"],"sources":["packages/team/agent-team/src/types.ts:47"]},
{"digest":"e0a787e6ec76c7c94fecbc501b489164ab0293db05bc947914077ad01e674f05","names":[],"sources":[]},
{"digest":"e1880c67e735e228f3555df8a55a492db2c0b0c71bc8859e938e184a46c7db51","names":[],"sources":["packages/core/agent/src/types.ts:110"]},
{"digest":"e272493e3ea0b33b2e1d64b6a80e9d8bd3d1d466cc115f2facbdd598f8644a39","names":["packages/llm/llm/src/message.ts#Message"],"sources":["packages/llm/llm/src/message.ts:196"]},
{"digest":"e2ad8f5bcd813f268ffef1b10a12d7ddd2b8ced8b9b6d0275b3f6b7ed094a187","names":[],"sources":[]},
{"digest":"e2d0367e5716bc188435e51718ebff8ce873190625fa93b1c5331102d98758fa","names":[],"sources":[]},
{"digest":"e2f9a41e0989f54ed8cee80f8db2bcf9d60a5c810dc9d45b83fa050b9dce7602","names":[],"sources":[]},
@@ -684,6 +685,7 @@
{"digest":"f6afe41e3926f422fe849debe90819fddd739f0f59e20be9c71018b9554a7f09","names":[],"sources":[]},
{"digest":"f6cb462f808309e315fea634f1ed86268b8346bbcee6774d9097ca6eed7ac1f8","names":[],"sources":[]},
{"digest":"f7283223aacdc39b0adca728c8cbd4c090a20006a6fecec74421c30e943b489c","names":[],"sources":[]},
{"digest":"f7752f518bb2f9165f2c01559df1f570c23d57373defbbd4512399a0ffaf2492","names":[],"sources":["packages/core/agent/src/types.ts:110"]},
{"digest":"f789af5ab844827eb5a4f357c0afae1eeed108c6c22d8ca1a56e586b349a7c85","names":[],"sources":[]},
{"digest":"f88f1b7b6bb733f685f5fb6a8744a5db9199fa53c90463ea1a33bad51153671d","names":[],"sources":[]},
{"digest":"f90eb4ab2d3897bc20c521a038e3119d581f791ec974b1a0004f63a8ab9e232d","names":[],"sources":["packages/core/session/src/types.ts:294","packages/deliverables/workspace-changes/src/types.ts:106"]},
@@ -706,7 +708,6 @@
],
"nodes": {
"0116b1f89c05221d": {"kind":"literal","value":"web_search_20250305"},
"01c161379a3c3394": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"589d0d91239681f8","optional":false},{"name":"source","type":"b120362fd216a16a","optional":false,"compatibility":{"version":1,"policy":"session-source-attribution","binding":"session.developer-message.source","discriminator":"kind","unknownKinds":"preserve","attributionKinds":["action-cards","tmux-context","user-question-reply","working-directory"]}}],"indices":[]},
"0203243b72fc867a": {"kind":"object","properties":[{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
"022623b9ef98ec47": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"023a355b2be0d688": {"kind":"object","properties":[{"name":"kind","type":"254dce209e735f9c","optional":false}],"indices":[]},
@@ -759,6 +760,7 @@
"15495614ccfa9cbd": {"kind":"literal","value":"codex"},
"1571525adc95a24e": {"kind":"literal","value":"never"},
"15d5dfdd822aa35e": {"kind":"object","properties":[{"name":"data","type":"54f9276a1617d7c1","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"e95f957154b2b1b5","optional":false}],"indices":[]},
"1682631f010d5ea7": {"kind":"object","properties":[{"name":"data","type":"f7752f518bb2f916","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"829a2fb3be6efd4b","optional":false}],"indices":[]},
"16d0507cb94b4cfc": {"kind":"literal","value":"relay"},
"17aae616ef020b8b": {"kind":"literal","value":"at"},
"17d1afb770d99419": {"kind":"object","properties":[{"name":"inherited","type":"dacf3d5f3e4ff619","optional":true}],"indices":[]},
@@ -812,6 +814,7 @@
"287211846beea1ec": {"kind":"object","properties":[{"name":"kind","type":"6c1cccb433ddc153","optional":false}],"indices":[]},
"28936c614bd4e7e2": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"d9edf1862e4471d6","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"290f32bfd81ff85a": {"kind":"object","properties":[{"name":"kind","type":"23af3759678a30de","optional":false}],"indices":[]},
"295809283ede248d": {"kind":"object","properties":[{"name":"headerSeq","type":"0657d3ca5ac4e7bf","optional":true},{"name":"message","type":"824b1d4d4f007bda","optional":false},{"name":"step","type":"0657d3ca5ac4e7bf","optional":false},{"name":"turn","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"297fbd8067d7815a": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false}],"indices":[]},
"2aad1179f9576314": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"2ab12a0e345658f9": {"kind":"array","element":"83da72c6857601c7"},
@@ -852,6 +855,7 @@
"3b1be838223869fe": {"kind":"object","properties":[{"name":"data","type":"e4c18e294232c3ba","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"c589e938cc0e4989","optional":false}],"indices":[]},
"3b4f2c9ef2c1217e": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false}],"indices":[]},
"3bc287e765d58dc3": {"kind":"literal","value":"normal"},
"3bca25b2baa6b22b": {"kind":"object","properties":[{"name":"data","type":"bec5ca3a376f56f3","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"587bb11da730e06a","optional":false}],"indices":[]},
"3bd652ebfa8726b3": {"kind":"union","types":["0657d3ca5ac4e7bf","938f7c7357bc403e"]},
"3bdb8dc6989655b0": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"a9059a81430b3207","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"3bec87f9e6ab3da0": {"kind":"object","properties":[{"name":"blockType","type":"7d65acf0a3a43a8f","optional":false},{"name":"index","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"cbca49bde16b656d","optional":false}],"indices":[]},
@@ -869,6 +873,7 @@
"408927267422a7b2": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"0fe52387f6505270","optional":false}],"indices":[]},
"4208123b50df5006": {"kind":"object","properties":[{"name":"data","type":"ad0c38a0adb82a94","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"3e0eff5946255ff0","optional":false}],"indices":[]},
"42e0916e0dda5f6d": {"kind":"object","properties":[{"name":"data","type":"7f9365bae9fcb73e","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"fe792a6cd4304945","optional":false}],"indices":[]},
"42e2ff61928fb7df": {"kind":"array","element":"c51f0d0a405bb96f"},
"4312134fc6f9cad5": {"kind":"literal","value":"turn/end"},
"43e311235aa537df": {"kind":"object","properties":[{"name":"toolName","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"83d6916021eede8f","optional":false}],"indices":[]},
"44818000e56acb97": {"kind":"literal","value":"feedback/message-delete"},
@@ -901,7 +906,9 @@
"4f507598cf476214": {"kind":"literal","value":"series"},
"4f91f187baeabef5": {"kind":"object","properties":[{"name":"capturedFormatVersion","type":"0657d3ca5ac4e7bf","optional":true},{"name":"capturedThroughSeq","type":"3bd652ebfa8726b3","optional":false},{"name":"compacted","type":"aa93010d0e521ad7","optional":false},{"name":"inputIndex","type":"0657d3ca5ac4e7bf","optional":false},{"name":"label","type":"4cd48f3e5108bd6e","optional":false},{"name":"omittedBytes","type":"0657d3ca5ac4e7bf","optional":false},{"name":"omittedMessages","type":"0657d3ca5ac4e7bf","optional":false},{"name":"originalMessages","type":"0657d3ca5ac4e7bf","optional":false},{"name":"retainedMessages","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sessionId","type":"4cd48f3e5108bd6e","optional":false},{"name":"truncated","type":"aa93010d0e521ad7","optional":false}],"indices":[]},
"4fb59762612c3e3a": {"kind":"object","properties":[{"name":"data","type":"b1ebd5cda47d90d9","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"18fcdd273a2f2f9d","optional":false}],"indices":[]},
"50a15408d511e9be": {"kind":"object","properties":[{"name":"data","type":"74e0e5885d2ddf04","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"de25352d2dc41963","optional":false}],"indices":[]},
"50cf02d875f8a1f1": {"kind":"union","types":["2da725e554cd8930","dd2780e7e0768433"]},
"510826cf4e1f9220": {"kind":"object","properties":[{"name":"data","type":"295809283ede248d","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"1379f0b72275994d","optional":false}],"indices":[]},
"511801b0a6470d98": {"kind":"literal","value":"success"},
"516da4cdd6d2f1e5": {"kind":"object","properties":[{"name":"data","type":"9890113e97dd3541","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"ca085dba2c877fec","optional":false}],"indices":[]},
"525254db03b1d1e6": {"kind":"object","properties":[{"name":"data","type":"c170da8ab7c37635","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"611cae9a3539733a","optional":false}],"indices":[]},
@@ -942,17 +949,15 @@
"5f2117d1856a5ab4": {"kind":"object","properties":[{"name":"code","type":"4cd48f3e5108bd6e","optional":false},{"name":"message","type":"4cd48f3e5108bd6e","optional":false},{"name":"offloadImages","type":"0657d3ca5ac4e7bf","optional":true},{"name":"providerRetryAfterMs","type":"0657d3ca5ac4e7bf","optional":true},{"name":"requestId","type":"4cd48f3e5108bd6e","optional":true},{"name":"status","type":"0657d3ca5ac4e7bf","optional":true}],"indices":[]},
"5f26a6c20b37632f": {"kind":"object","properties":[{"name":"data","type":"9a410ddf56792b2b","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"ad92f473a03ae725","optional":false}],"indices":[]},
"5f758f3de5f00c18": {"kind":"object","properties":[{"name":"label","type":"4cd48f3e5108bd6e","optional":true},{"name":"mode","type":"d28765f87d6b6ab4","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false},{"name":"version","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"601327bedca5f98a": {"kind":"object","properties":[{"name":"maxTokens","type":"0657d3ca5ac4e7bf","optional":false},{"name":"messageSeqs","type":"5d03ba38734809bc","optional":false},{"name":"messages","type":"95b5cf90ea1f57da","optional":false},{"name":"reasoningEffort","type":"4cd48f3e5108bd6e","optional":true},{"name":"route","type":"07e1a58c58b593f5","optional":false},{"name":"system","type":"4cd48f3e5108bd6e","optional":false},{"name":"titleProvider","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"6085488d223aeffd": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"611cae9a3539733a": {"kind":"literal","value":"llm/retry"},
"611d82d2dc50df70": {"kind":"object","properties":[{"name":"cause","type":"750a2b129d67704d","optional":false},{"name":"detail","type":"4cd48f3e5108bd6e","optional":true},{"name":"finishedAt","type":"0657d3ca5ac4e7bf","optional":false},{"name":"jobId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"4cd48f3e5108bd6e","optional":false},{"name":"label","type":"4cd48f3e5108bd6e","optional":false},{"name":"owner","type":"4cd48f3e5108bd6e","optional":false},{"name":"producerReported","type":"aa93010d0e521ad7","optional":false},{"name":"startedAt","type":"0657d3ca5ac4e7bf","optional":false},{"name":"status","type":"c2f49004d9ae38a9","optional":false},{"name":"toolCall","type":"39cf2d3ff8bac81c","optional":true}],"indices":[]},
"613660455704fb82": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"68f44f59e91c4139","optional":false},{"name":"source","type":"b120362fd216a16a","optional":false,"compatibility":{"version":1,"policy":"session-source-attribution","binding":"session.user-message.source","discriminator":"kind","unknownKinds":"preserve","attributionKinds":["action-cards","tmux-context","user-question-reply","working-directory"]}}],"indices":[]},
"616f93a5047de668": {"kind":"literal","value":"tool-call-chunks"},
"6292bcbedaa97fea": {"kind":"object","properties":[{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"62e6a429ff3f390a": {"kind":"union","types":["1d8798b1a5e8c545","1e346446e183ee76","34d1ab5c5df37818","7624ca28c61ca0ea","ad22a5ca5bbaab2e","d9196086e41e4dd5"]},
"62ecb62dc0fe1b5e": {"kind":"literal","value":"next-turn"},
"63ba8895cc09e469": {"kind":"literal","value":"retry"},
"6487b10ba7542f3c": {"kind":"object","properties":[{"name":"agentModel","type":"4cd48f3e5108bd6e","optional":true},{"name":"agentProvider","type":"4cd48f3e5108bd6e","optional":true},{"name":"agentReasoningEffort","type":"4cd48f3e5108bd6e","optional":true},{"name":"label","type":"4cd48f3e5108bd6e","optional":false},{"name":"mode","type":"e5d3828df1ec3e2a","optional":false},{"name":"persona","type":"4cd48f3e5108bd6e","optional":true},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false},{"name":"toolFilter","type":"3cfc3a56502da1f8","optional":true},{"name":"version","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"65377a76c6a58f78": {"kind":"object","properties":[{"name":"headerSeq","type":"0657d3ca5ac4e7bf","optional":true},{"name":"message","type":"01c161379a3c3394","optional":false},{"name":"step","type":"0657d3ca5ac4e7bf","optional":false},{"name":"turn","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"6598cd6da253948d": {"kind":"object","properties":[{"name":"context","type":"50cf02d875f8a1f1","optional":false},{"name":"description","type":"4cd48f3e5108bd6e","optional":false},{"name":"error","type":"4cd48f3e5108bd6e","optional":true},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false},{"name":"phase","type":"dfce5db4aa42b7eb","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"65a8400e451e667e": {"kind":"object","properties":[{"name":"kind","type":"09655b34d7f3cf1e","optional":false}],"indices":[]},
"65d583e66518c523": {"kind":"object","properties":[{"name":"entries","type":"aba175fb20ffc711","optional":false},{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"incomplete","type":"dacf3d5f3e4ff619","optional":true},{"name":"kind","type":"6ebcc2dbec9f2dab","optional":false},{"name":"update","type":"dacf3d5f3e4ff619","optional":true}],"indices":[]},
@@ -962,7 +967,6 @@
"68141cbe3994a5ff": {"kind":"literal","value":"max-tokens"},
"688e853dc149f0d3": {"kind":"literal","value":"reasoning-chunks"},
"68f44f59e91c4139": {"kind":"literal","value":"user"},
"690583582246babf": {"kind":"array","element":"613660455704fb82"},
"69081694be231d56": {"kind":"object","properties":[{"name":"data","type":"6bc8e51124d0874b","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"1c5a58f4599bd4a9","optional":false}],"indices":[]},
"693f4952fb5565da": {"kind":"object","properties":[{"name":"failure","type":"5f2117d1856a5ab4","optional":false},{"name":"kind","type":"a2be0f0cb59f0d4a","optional":false}],"indices":[]},
"69d238a6e9b08d67": {"kind":"literal","value":"interrupted"},
@@ -987,12 +991,12 @@
"6f72ece8f317cd08": {"kind":"object","properties":[{"name":"retry","type":"0657d3ca5ac4e7bf","optional":false},{"name":"retryId","type":"4cd48f3e5108bd6e","optional":false},{"name":"step","type":"0657d3ca5ac4e7bf","optional":false},{"name":"turn","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"6f9e00383836275e": {"kind":"literal","value":"snapshot"},
"70b082fe78991edf": {"kind":"literal","value":"request/context"},
"70ea8e7943c5e2d7": {"kind":"object","properties":[{"name":"data","type":"65377a76c6a58f78","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"1379f0b72275994d","optional":false}],"indices":[]},
"7180844e1066230c": {"kind":"literal","value":"service-stability"},
"719c51f67074f970": {"kind":"object","properties":[{"name":"kind","type":"2765e9119edf5816","optional":false},{"name":"model","type":"4cd48f3e5108bd6e","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false},{"name":"replayState","type":"bbc5696e3f13c758","optional":true}],"indices":[]},
"71bb3254ec8f1e49": {"kind":"object","properties":[{"name":"dt","type":"5d03ba38734809bc","optional":false},{"name":"index","type":"0657d3ca5ac4e7bf","optional":false},{"name":"texts","type":"93c33d9687613293","optional":false},{"name":"time0","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"688e853dc149f0d3","optional":false}],"indices":[]},
"72ec79127a9c0d02": {"kind":"array","element":"c592ce75aab73fca"},
"7382c4fc95fe8c5d": {"kind":"literal","value":"remove"},
"74e0e5885d2ddf04": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"68f44f59e91c4139","optional":false},{"name":"source","type":"dca3ba43188095fa","optional":false,"compatibility":{"version":1,"policy":"session-source-attribution","binding":"session.user-message.source","discriminator":"kind","unknownKinds":"preserve","attributionKinds":["action-cards","tmux-context","user-question-reply","working-directory"]}}],"indices":[]},
"750a2b129d67704d": {"kind":"union","types":["5cb63db9fe57dc09","6cf082d0fb6034de","bab6865794007548"]},
"7554565be416b034": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"756b5e23a5cb2c7f": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
@@ -1023,6 +1027,7 @@
"814d9434e1ddf907": {"kind":"object","properties":[{"name":"text","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"3c2535ca0a2062f1","optional":false}],"indices":[]},
"82470020b5bfcb1a": {"kind":"literal","value":"agent-message"},
"824a4aad44a54e24": {"kind":"union","types":["4d60dddaa65d3da8","deebfc7c62177ea8"]},
"824b1d4d4f007bda": {"kind":"object","properties":[{"name":"content","type":"b52f215a6cd69105","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"role","type":"589d0d91239681f8","optional":false},{"name":"source","type":"dca3ba43188095fa","optional":false,"compatibility":{"version":1,"policy":"session-source-attribution","binding":"session.developer-message.source","discriminator":"kind","unknownKinds":"preserve","attributionKinds":["action-cards","tmux-context","user-question-reply","working-directory"]}}],"indices":[]},
"825ca23416b1ea9d": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"f68c335306535a00","optional":false}],"indices":[]},
"829a2fb3be6efd4b": {"kind":"literal","value":"agent/inbox/spliced"},
"83079c8a3f733ac3": {"kind":"object","properties":[{"name":"description","type":"4cd48f3e5108bd6e","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
@@ -1046,6 +1051,7 @@
"88841202942c7683": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"bb94f3217aa56c88","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"88a610b831be6d92": {"kind":"object","properties":[{"name":"argumentsDelta","type":"4cd48f3e5108bd6e","optional":false},{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"index","type":"0657d3ca5ac4e7bf","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":true},{"name":"type","type":"9b4fd974c124c837","optional":false}],"indices":[]},
"8a046b52331959aa": {"kind":"object","properties":[{"name":"kind","type":"78a9be340090b735","optional":false}],"indices":[]},
"8a54d228b1b7d845": {"kind":"array","element":"74e0e5885d2ddf04"},
"8a6e1ec9e8db346b": {"kind":"object","properties":[{"name":"data","type":"119abe2b9c0b2f46","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"b9305f0ea75ccd6a","optional":false}],"indices":[]},
"8a9c990773f798ea": {"kind":"object","properties":[{"name":"preset","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"8ad45ad053b4d89f": {"kind":"object","properties":[{"name":"decision","type":"4cd48f3e5108bd6e","optional":false},{"name":"durationMs","type":"0657d3ca5ac4e7bf","optional":false},{"name":"exitCode","type":"0657d3ca5ac4e7bf","optional":true},{"name":"handlerId","type":"4cd48f3e5108bd6e","optional":false},{"name":"point","type":"4cd48f3e5108bd6e","optional":false},{"name":"stderrSummary","type":"4cd48f3e5108bd6e","optional":true},{"name":"turn","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
@@ -1058,6 +1064,7 @@
"8e611bf46821e500": {"kind":"object","properties":[{"name":"tool","type":"fcf427290c6213c2","optional":true},{"name":"toolName","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"85f9b505b7bdff1f","optional":false}],"indices":[]},
"8e8155594e078123": {"kind":"literal","value":"workspace/changes"},
"8e8e91646a5cae3f": {"kind":"object","properties":[{"name":"id","type":"4cd48f3e5108bd6e","optional":false},{"name":"operation","type":"26c879bdd130e8b8","optional":false},{"name":"version","type":"f88f1b7b6bb733f6","optional":false}],"indices":[]},
"8f1062573ea91841": {"kind":"object","properties":[{"name":"clientTimeZone","type":"4cd48f3e5108bd6e","optional":true},{"name":"kind","type":"63ba8895cc09e469","optional":false},{"name":"principal","type":"824a4aad44a54e24","optional":true},{"name":"rpcId","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"8f324cea3916c051": {"kind":"object","properties":[{"name":"form","type":"16d0507cb94b4cfc","optional":false},{"name":"kind","type":"2f3f201c8846e19c","optional":false}],"indices":[]},
"8f6d609794bf5afc": {"kind":"tuple","elements":[{"type":"4e88776858652856","optional":false,"rest":false}]},
"8faed5b52ab2d2df": {"kind":"object","properties":[{"name":"childCreatedAt","type":"0657d3ca5ac4e7bf","optional":false},{"name":"childId","type":"4cd48f3e5108bd6e","optional":false},{"name":"label","type":"4cd48f3e5108bd6e","optional":false},{"name":"mode","type":"e5d3828df1ec3e2a","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":false},{"name":"version","type":"137ac60e26bcb192","optional":false}],"indices":[]},
@@ -1073,7 +1080,6 @@
"94c56aeb1564ad73": {"kind":"literal","value":"in_progress"},
"95080295115fbd83": {"kind":"object","properties":[{"name":"index","type":"0657d3ca5ac4e7bf","optional":false},{"name":"text","type":"4cd48f3e5108bd6e","optional":false},{"name":"type","type":"5abab3a27fd27366","optional":false}],"indices":[]},
"95a3ffccbf3c8afc": {"kind":"literal","value":"owner"},
"95b5cf90ea1f57da": {"kind":"array","element":"e272493e3ea0b33b"},
"95c0e88fcf0bafb2": {"kind":"literal","value":"assistant"},
"9645cf93769a6dfb": {"kind":"literal","value":"user-question-reply"},
"96bfb916a727cd44": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"24b10f7cdae64928","optional":false}],"indices":[]},
@@ -1149,7 +1155,6 @@
"b0127044ab31a702": {"kind":"object","properties":[{"name":"data","type":"ca59530d1a4f3e19","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"1986c2664009c991","optional":false}],"indices":[]},
"b062078e899958f9": {"kind":"object","properties":[{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"b0b0eb1b16490f6b": {"kind":"object","properties":[{"name":"attachmentId","type":"4cd48f3e5108bd6e","optional":false},{"name":"bytes","type":"0657d3ca5ac4e7bf","optional":false},{"name":"height","type":"0657d3ca5ac4e7bf","optional":false},{"name":"mediaType","type":"2f1e6a7ebace43d7","optional":false},{"name":"name","type":"4cd48f3e5108bd6e","optional":true},{"name":"originalDimensions","type":"0f46153645c29784","optional":true},{"name":"width","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"b120362fd216a16a": {"kind":"union","types":["0203243b72fc867a","022623b9ef98ec47","02b2c23f2d94b028","0ed8d1108fe7a5e1","0eeb17e1df89b1eb","11638dc58a31496f","1938c8c20f1cba7c","1e709346005826eb","1fdad624334d3548","2152caf1a71e588e","2235d957bf4b7c6c","224aa11d4d5f88c4","24ce31aa528272e5","260523b412c19ad8","28936c614bd4e7e2","290f32bfd81ff85a","297fbd8067d7815a","2aad1179f9576314","312aee2f0c42aabb","31907de956375182","3247e566f4340029","3b04790e08b35241","3b4f2c9ef2c1217e","3bdb8dc6989655b0","408927267422a7b2","45f005e6bbb76452","4991dfc415c9efeb","49dab019d00e8c26","4a9bef9f27a94252","52c6113cb0e53f34","53cf1704ae0709c7","5654685d7557ec74","58015da1c1950a66","5bb69b88517f6214","5bc66269cfaf614c","5cdbf342b7748d15","5d7a64ed6aac5551","6085488d223aeffd","6292bcbedaa97fea","65a8400e451e667e","65d583e66518c523","672c4aa2a9b736e3","6ccb6bc423fb3952","6ea608bdc8a7a63d","6f22a9d02b9a1f11","6f44f32be9bcd9a8","719c51f67074f970","7554565be416b034","756b5e23a5cb2c7f","7df62978a2b7de85","7eaef7a763ba5b94","7f959241c24128b4","80677c8c8b804189","825ca23416b1ea9d","8338ee303e2bd448","848639f8787f035b","854db3efdfb0cd39","85fe96bf15d5c755","8620189c8e335827","87b1a33564b9a4d6","88841202942c7683","8a046b52331959aa","8c1c4f72755a78ea","8c627d7a45fa406c","8f324cea3916c051","8fcb0b44a575e998","96bfb916a727cd44","99135d8a39379779","99f0e98184709ad1","9edc162949abf93b","9f65c43e340bba31","a15a19ef63cf5d1b","a16e567c8cd2c55c","a2066bd52f61218b","a3c6f1ea38e9a61d","a4afec59b75aad5d","aa2bf9e82b9fdeb9","aae343bc3d663c83","ada310bf0bdb8fed","ade057f4fdc387ae","b062078e899958f9","b2a5c8c008a31e3d","b3681c026a0b98e9","b4ec0af39fd52ed9","b613f83572fe2fbf","b6f94c17dd9bbd7c","b70f3e81fe11b7a5","b79641a9d25e7566","ba2a1a8f194b1bb2","ba4c40b4381e0dcd","baccc97ec34be6c4","c5228b7a55498d84","c55827fba7018198","cb1c8959e1726f82","cda2345a9be9d139","d85590a5675c6e2f","d9c462b9f62fdd3e","db06ef35b27a3842","dba54c09c6e7aafc","dd00cdccd0ba487b","dd5ee8762bd8a14b","dd6cc2bb2a8f2824","dde0cdf9d426768b","deaae5cd30987d4f","e7f4cbb3a57f4cbd","edbbfff1128099fd","ee577a0cc18664c9","f230c0b583e23b25","f29d63336e8266d8","f4a66f654996c093","f56c5b59ca016131","f6329fb30c7ea801","f6605d6c57933aea","f6afe41e3926f422","f7283223aacdc39b","f97f47b0eb87905e","fcf81d3c58c13593","fe1a7acdeed4d0f5"]},
"b158f3ff69237148": {"kind":"object","properties":[{"name":"contextWindow","type":"0657d3ca5ac4e7bf","optional":true},{"name":"model","type":"4cd48f3e5108bd6e","optional":false},{"name":"provider","type":"4cd48f3e5108bd6e","optional":false},{"name":"systemPromptUpdate","type":"f311671e07bc7fa6","optional":true}],"indices":[]},
"b1664fa89f8eab49": {"kind":"array","element":"bbc5696e3f13c758"},
"b1ebd5cda47d90d9": {"kind":"object","properties":[{"name":"member","type":"6598cd6da253948d","optional":false},{"name":"teamId","type":"4cd48f3e5108bd6e","optional":false},{"name":"version","type":"a0f906856fc06f1c","optional":false}],"indices":[]},
@@ -1195,6 +1200,7 @@
"bca0f9cb63d8620b": {"kind":"object","properties":[{"name":"data","type":"a9427866376b691a","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"b57ae1b37e52bee0","optional":false}],"indices":[]},
"bcf0caf62d964b2f": {"kind":"object","properties":[{"name":"endSeq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"op","type":"f6cb462f808309e3","optional":false},{"name":"startSeq","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"bd499eac047efe09": {"kind":"literal","value":"finish"},
"bec5ca3a376f56f3": {"kind":"object","properties":[{"name":"maxTokens","type":"0657d3ca5ac4e7bf","optional":false},{"name":"messageSeqs","type":"5d03ba38734809bc","optional":false},{"name":"messages","type":"42e2ff61928fb7df","optional":false},{"name":"reasoningEffort","type":"4cd48f3e5108bd6e","optional":true},{"name":"route","type":"07e1a58c58b593f5","optional":false},{"name":"system","type":"4cd48f3e5108bd6e","optional":false},{"name":"titleProvider","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
"bf16d2e98a7f1389": {"kind":"literal","value":"subagent-settled"},
"c0ea97bc89dfc46f": {"kind":"object","properties":[{"name":"outcome","type":"c2deb7c9183735d4","optional":false},{"name":"runId","type":"4cd48f3e5108bd6e","optional":false},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"c170da8ab7c37635": {"kind":"union","types":["374fdd68aee5ff84","cdee10e87dbed844"]},
@@ -1205,6 +1211,7 @@
"c2deb7c9183735d4": {"kind":"union","types":["1ebc6f9ff3aa9e3a","2142e391b9ccb60d","b57a2889408de36e"]},
"c2f49004d9ae38a9": {"kind":"union","types":["1ebc6f9ff3aa9e3a","b57a2889408de36e","ef226a90ddac6cd8"]},
"c43b119ce579b3e9": {"kind":"literal","value":"paused"},
"c51f0d0a405bb96f": {"kind":"union","types":["09f3f8dc417f2782","4b259f7f8f0a44ad","74e0e5885d2ddf04","824b1d4d4f007bda","fa87537f4a9c1e25"]},
"c5228b7a55498d84": {"kind":"object","properties":[{"name":"form","type":"6f9e00383836275e","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false},{"name":"sections","type":"c748fb42c80a1200","optional":false}],"indices":[]},
"c55827fba7018198": {"kind":"object","properties":[{"name":"callId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"9645cf93769a6dfb","optional":false},{"name":"outcome","type":"85d6d96ff8842974","optional":false}],"indices":[]},
"c5687b1313206a6f": {"kind":"literal","value":"cordis-host-runner"},
@@ -1236,7 +1243,6 @@
"d85590a5675c6e2f": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"1f1385dbc3e875c0","optional":false}],"indices":[]},
"d8a476d2c6fd30df": {"kind":"literal","value":"team/mode"},
"d9196086e41e4dd5": {"kind":"literal","value":"complete"},
"d95c624eddecdacf": {"kind":"object","properties":[{"name":"data","type":"601327bedca5f98a","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"587bb11da730e06a","optional":false}],"indices":[]},
"d9c462b9f62fdd3e": {"kind":"object","properties":[{"name":"callId","type":"4cd48f3e5108bd6e","optional":false},{"name":"kind","type":"a13d8f379222ece8","optional":false}],"indices":[]},
"d9edf1862e4471d6": {"kind":"literal","value":"schedule"},
"da60ed58a8fa23d7": {"kind":"object","properties":[{"name":"cwd","type":"4cd48f3e5108bd6e","optional":false}],"indices":[]},
@@ -1246,12 +1252,11 @@
"db874d463b0fdec7": {"kind":"object","properties":[{"name":"data","type":"3e4e7683b0192c9f","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"e2d0367e5716bc18","optional":false}],"indices":[]},
"dba54c09c6e7aafc": {"kind":"object","properties":[{"name":"kind","type":"4edec1b770e8ec4c","optional":false}],"indices":[]},
"dbdafceb9a900183": {"kind":"literal","value":"hook"},
"dcb07e04496586d2": {"kind":"object","properties":[{"name":"data","type":"613660455704fb82","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"sourceEventSeqs","type":"5d03ba38734809bc","optional":true},{"name":"surfaceOp","type":"335e242de1fcc17b","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"de25352d2dc41963","optional":false}],"indices":[]},
"dca3ba43188095fa": {"kind":"union","types":["0203243b72fc867a","022623b9ef98ec47","02b2c23f2d94b028","0ed8d1108fe7a5e1","0eeb17e1df89b1eb","11638dc58a31496f","1938c8c20f1cba7c","1e709346005826eb","1fdad624334d3548","2152caf1a71e588e","2235d957bf4b7c6c","224aa11d4d5f88c4","24ce31aa528272e5","260523b412c19ad8","28936c614bd4e7e2","290f32bfd81ff85a","297fbd8067d7815a","2aad1179f9576314","312aee2f0c42aabb","31907de956375182","3247e566f4340029","3b04790e08b35241","3b4f2c9ef2c1217e","3bdb8dc6989655b0","408927267422a7b2","45f005e6bbb76452","4991dfc415c9efeb","49dab019d00e8c26","4a9bef9f27a94252","52c6113cb0e53f34","53cf1704ae0709c7","5654685d7557ec74","58015da1c1950a66","5bb69b88517f6214","5bc66269cfaf614c","5cdbf342b7748d15","5d7a64ed6aac5551","6085488d223aeffd","6292bcbedaa97fea","65a8400e451e667e","65d583e66518c523","672c4aa2a9b736e3","6ccb6bc423fb3952","6ea608bdc8a7a63d","6f22a9d02b9a1f11","6f44f32be9bcd9a8","719c51f67074f970","7554565be416b034","756b5e23a5cb2c7f","7df62978a2b7de85","7eaef7a763ba5b94","7f959241c24128b4","80677c8c8b804189","825ca23416b1ea9d","8338ee303e2bd448","848639f8787f035b","854db3efdfb0cd39","85fe96bf15d5c755","8620189c8e335827","87b1a33564b9a4d6","88841202942c7683","8a046b52331959aa","8c1c4f72755a78ea","8c627d7a45fa406c","8f1062573ea91841","8f324cea3916c051","8fcb0b44a575e998","96bfb916a727cd44","99135d8a39379779","99f0e98184709ad1","9edc162949abf93b","9f65c43e340bba31","a15a19ef63cf5d1b","a16e567c8cd2c55c","a2066bd52f61218b","a3c6f1ea38e9a61d","a4afec59b75aad5d","aa2bf9e82b9fdeb9","aae343bc3d663c83","ada310bf0bdb8fed","ade057f4fdc387ae","b062078e899958f9","b2a5c8c008a31e3d","b3681c026a0b98e9","b4ec0af39fd52ed9","b613f83572fe2fbf","b6f94c17dd9bbd7c","b70f3e81fe11b7a5","b79641a9d25e7566","ba2a1a8f194b1bb2","ba4c40b4381e0dcd","baccc97ec34be6c4","c5228b7a55498d84","c55827fba7018198","cb1c8959e1726f82","cda2345a9be9d139","d85590a5675c6e2f","d9c462b9f62fdd3e","db06ef35b27a3842","dba54c09c6e7aafc","dd00cdccd0ba487b","dd5ee8762bd8a14b","dd6cc2bb2a8f2824","dde0cdf9d426768b","deaae5cd30987d4f","e7f4cbb3a57f4cbd","edbbfff1128099fd","ee577a0cc18664c9","f230c0b583e23b25","f29d63336e8266d8","f4a66f654996c093","f56c5b59ca016131","f6329fb30c7ea801","f6605d6c57933aea","f6afe41e3926f422","f7283223aacdc39b","f97f47b0eb87905e","fcf81d3c58c13593","fe1a7acdeed4d0f5"]},
"dd00cdccd0ba487b": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"dd2780e7e0768433": {"kind":"literal","value":"fresh"},
"dd5ee8762bd8a14b": {"kind":"object","properties":[{"name":"form","type":"aec150797b655c5f","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"dd6cc2bb2a8f2824": {"kind":"object","properties":[{"name":"form","type":"383cf73ae4748e5b","optional":false},{"name":"kind","type":"99e7e7d7fed55ae6","optional":false}],"indices":[]},
"ddce54a3873dc571": {"kind":"object","properties":[{"name":"data","type":"e1880c67e735e228","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"829a2fb3be6efd4b","optional":false}],"indices":[]},
"dde0cdf9d426768b": {"kind":"object","properties":[{"name":"kind","type":"05205074b24d8340","optional":false},{"name":"through","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
"de25352d2dc41963": {"kind":"literal","value":"user/message"},
"de30b1fa12c75f81": {"kind":"literal","value":"image/gif"},
@@ -1261,8 +1266,6 @@
"df843efd87c78cf8": {"kind":"array","element":"4f91f187baeabef5"},
"dfce5db4aa42b7eb": {"kind":"union","types":["871bfd6f7bb91061","b57a2889408de36e","c8e6f48878cc2a2f"]},
"e0a787e6ec76c7c9": {"kind":"object","properties":[{"name":"data","type":"ef11a3b7fa2033ae","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"c219efbdfd53b836","optional":false}],"indices":[]},
"e1880c67e735e228": {"kind":"object","properties":[{"name":"inserted","type":"690583582246babf","optional":false},{"name":"outcome","type":"d4e4d575abeb4b72","optional":true},{"name":"removedCount","type":"0657d3ca5ac4e7bf","optional":true},{"name":"start","type":"0657d3ca5ac4e7bf","optional":false},{"name":"target","type":"96f4a9c81fc0f940","optional":false}],"indices":[]},
"e272493e3ea0b33b": {"kind":"union","types":["01c161379a3c3394","09f3f8dc417f2782","4b259f7f8f0a44ad","613660455704fb82","fa87537f4a9c1e25"]},
"e2ad8f5bcd813f26": {"kind":"object","properties":[{"name":"childCreatedAt","type":"0657d3ca5ac4e7bf","optional":false},{"name":"childId","type":"4cd48f3e5108bd6e","optional":false},{"name":"label","type":"4cd48f3e5108bd6e","optional":false},{"name":"mode","type":"e5d3828df1ec3e2a","optional":false},{"name":"version","type":"f88f1b7b6bb733f6","optional":false}],"indices":[]},
"e2d0367e5716bc18": {"kind":"literal","value":"compaction/start"},
"e2f9a41e0989f54e": {"kind":"object","properties":[{"name":"data","type":"9947aa5938fe19a8","optional":false},{"name":"ignorable","type":"dacf3d5f3e4ff619","optional":true},{"name":"seq","type":"0657d3ca5ac4e7bf","optional":false},{"name":"time","type":"0657d3ca5ac4e7bf","optional":false},{"name":"type","type":"ef4f00923b9edbae","optional":false}],"indices":[]},
@@ -1320,6 +1323,7 @@
"f6afe41e3926f422": {"kind":"object","properties":[{"name":"form","type":"fee1caf8ab6a65c1","optional":false},{"name":"kind","type":"8067b0d232c350f1","optional":false}],"indices":[]},
"f6cb462f808309e3": {"kind":"literal","value":"replace"},
"f7283223aacdc39b": {"kind":"object","properties":[{"name":"kind","type":"9ac52f0f84fec2eb","optional":false}],"indices":[]},
"f7752f518bb2f916": {"kind":"object","properties":[{"name":"inserted","type":"8a54d228b1b7d845","optional":false},{"name":"outcome","type":"d4e4d575abeb4b72","optional":true},{"name":"removedCount","type":"0657d3ca5ac4e7bf","optional":true},{"name":"start","type":"0657d3ca5ac4e7bf","optional":false},{"name":"target","type":"96f4a9c81fc0f940","optional":false}],"indices":[]},
"f789af5ab844827e": {"kind":"literal","value":"change"},
"f88f1b7b6bb733f6": {"kind":"literal","value":1},
"f90eb4ab2d3897bc": {"kind":"object","properties":[{"name":"turn","type":"0657d3ca5ac4e7bf","optional":false}],"indices":[]},
@@ -24,8 +24,8 @@
en: 954923654eebe2dc
zh: 6bd9a7d2ea965aed
/session-controller/configuration:
en: c92590fbaf75e45e
zh: fcac67017bb0e3ab
en: 8f62f7183c67fc02
zh: 0e2db400b376629f
/session-controller/model-experience:
en: 30b917bf822bb4df
zh: b0b023b5b526c317
@@ -110,6 +110,8 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a
Blockquotes travel as ordinary prompt text without quote metadata. Local submission echoes and durable messages use the same text rendering rules; queue edits replace content while retaining prompt correlation.
An empty `prompt.content` array requests a new turn only for an eligible failed, idle ordinary Session in queue mode. Pending human input prevents admission; non-waking injected context is retained. `conversationContinuation` supplies the shared six-code manual policy, independently of provider retry configuration. The input follows ordinary inbox and Loop admission and records an empty `user/message` with `source.kind: 'retry'`; its input identity and caller metadata support deduplication and recovery. Whitespace-only text parts remain invalid.
<a id="model-experience"></a>
## Model Experience
@@ -110,6 +110,8 @@ GUI 模型选择要求确切提供方/模型对出现在可用目录中;不
Blockquote 作为普通 prompt 文本传递,不携带 quote 元数据。本地提交回显与持久消息使用同一文本渲染规则;队列编辑替换 content,同时保留 prompt 关联信息。
空的 `prompt.content` 数组仅在普通 Session 空闲、最新失败符合继续条件且使用 queue 模式时请求新轮次。待消费的用户输入阻止准入,非唤醒的注入上下文保留。`conversationContinuation` 提供共用的六码手动策略,独立于提供方重试配置。输入遵循普通 inbox 和 Loop 准入,记录带 `source.kind: 'retry'` 的空 `user/message`;输入身份与调用方元数据用于去重和恢复。仅含空白的文本块仍无效。
<a id="model-experience"></a>
## 模型体验
@@ -1,5 +1,8 @@
/** Session commands whose activation policy is explicit at each Remote method. */
import type { ProjectionHandle } from '@deepseek-ai/dsh-session-projection'
import { continuationProjectionDefinition, type ContinuationState } from './continuation.ts'
import { modelAvailable } from './catalog.ts'
import { randomUUID } from 'node:crypto'
import type { Context } from '@deepseek-ai/cordis'
@@ -59,7 +62,7 @@ type PromptContentCandidate =
/**
* Whether prompt content carries non-whitespace text or an attachment.
* @param content - submitted or edited prompt parts.
* @returns false for content the Agent must not receive.
* @returns whether any part supplies ordinary prompt content.
*/
export function hasPromptContent(content: readonly PromptContentCandidate[]): boolean {
return content.some(part => part.type !== 'text' || part.text.trim().length > 0)
@@ -83,6 +86,13 @@ function latestCompletedPrefixBoundary(events: readonly SessionEvent[]): Session
/** Implements Session business commands delegated by the Session Controller Remote service. */
export class SessionCommandController {
private continuation!: ProjectionHandle<ContinuationState>
/** Register complete-history empty-prompt eligibility. @returns when command admission is ready. */
async initialize(): Promise<void> {
this.continuation = await this.ctx.sessionProjections.register(continuationProjectionDefinition)
}
/**
* @param ctx - Host context carrying Agent, model, attachment, title, and Workspace services.
* @param agents - sole owner of create, resume, and Agent composition.
@@ -298,12 +308,28 @@ export class SessionCommandController {
* Admit one prompt after Agent and attachment validation; the Remote method
* has already validated the content and built the durable message source.
* @param request - Session identity, prompt content, and delivery mode.
* @param source - the `user-rpc` source recorded on the accepted message.
* @param source - caller metadata recorded on the accepted ordinary or retry user message.
* @returns acknowledgement that the Agent accepted the prompt.
*/
async prompt(request: SessionPromptRequest, source: MessageSource): Promise<SessionPromptValue> {
const agent = await this.resolveAgent(request.sessionId)
if (hasPromptRequest(agent, request.requestId)) return { accepted: true }
if (request.content.length === 0) {
try {
return await agent.runMaintenance(() => {
const inbox = agent.inbox
if (request.mode !== 'queue' || this.continuation.stateOf(agent.session).ending === null
|| inbox.nextTurn.length > 0 || inbox.nextStep.some(message => message.source.kind === 'user')) {
throw new RemoteError('session/agent-busy', 'generation continuation is unavailable', { reason: 'NO_CONTINUABLE_FAILURE_OR_PENDING_INPUT' })
}
agent.followup(createUserMessage({ content: [], source }))
return Promise.resolve({ accepted: true as const })
})
} catch (error: unknown) {
if (remoteErrorOf(error) !== undefined) throw error
throw new RemoteError('session/agent-busy', 'generation continuation was not accepted', { reason: String(error) })
}
}
const admission = resolvePromptFileReceipts(
request.content,
receiptId => this.ctx.fileUploads.resolve(agent, receiptId),
@@ -542,13 +568,12 @@ function resolvePromptFileReceipts(
function hasPromptRequest(agent: Agent, requestId: SessionRequestId): boolean {
const matches = (message: UserMessage): boolean => {
const source = message.source
return source.kind === 'user' && 'rpcId' in source && source.rpcId === requestId
return (source.kind === 'user' || source.kind === 'retry') && 'rpcId' in source && source.rpcId === requestId
}
if (agent.inbox.nextTurn.some(matches) || agent.inbox.nextStep.some(matches)) return true
// oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred.
return agent.session.snapshotEvents().some((event) => {
if (event.type !== 'user/message') return false
const source = event.data.source
return source.kind === 'user' && 'rpcId' in source && source.rpcId === requestId
return matches(event.data)
})
}
@@ -0,0 +1,58 @@
/** Constant-size continuation eligibility over the complete durable Session. */
import type {} from './types.ts'
import type { ProjectionDefinition } from '@deepseek-ai/dsh-session-projection'
import type { SessionSeq } from '@deepseek-ai/dsh-session/types'
import { brandNumber } from '@deepseek-ai/dsh-brand'
import { z } from 'zod'
// Explicit manual requests use a fixed product policy, independent of automatic retry configuration.
const CONTINUABLE_FAILURES: ReadonlySet<string> = new Set([
'RATE_LIMIT', 'SERVER', 'TIMEOUT', 'TRANSPORT', 'EMPTY_RESPONSE', 'STREAM_CLOSED',
])
const endingSchema = z.number().int().nonnegative().transform(brandNumber<SessionSeq>).nullable()
const stateSchema = z.object({
admitted: z.boolean(),
failedAttempt: z.boolean(),
ending: endingSchema,
})
/** Recoverable manual-continuation facts over admitted user input and empty retry messages. */
export type ContinuationState = z.infer<typeof stateSchema>
const EMPTY: ContinuationState = { admitted: false, failedAttempt: false, ending: null }
/** Eligibility requires admitted human work and a failed settlement in the last request step. */
export const continuationProjectionDefinition = {
key: 'conversationContinuation',
stateVersion: 4,
stateSchema,
init: (): ContinuationState => EMPTY,
apply: (state, event) => {
switch (event.type) {
case 'turn/start':
return EMPTY
case 'step/start':
case 'assistant/message':
return state.failedAttempt ? { ...state, failedAttempt: false } : state
case 'user/message':
return !state.admitted && event.surfaceOp === 'append'
&& ((event.data.source.kind === 'user' && event.data.content.length > 0)
|| (event.data.source.kind === 'retry' && event.data.content.length === 0))
? { ...state, admitted: true } : state
case 'assistant/attempt':
return state.failedAttempt ? state : { ...state, failedAttempt: true }
case 'turn/end': {
const ending = event.data.reason.kind === 'error' && CONTINUABLE_FAILURES.has(event.data.reason.error.code)
&& state.admitted && state.failedAttempt ? event.seq : null
return ending === null ? EMPTY : { ...EMPTY, ending }
}
default:
return state
}
},
wire: {
viewSchema: endingSchema,
view: (state: ContinuationState) => state.ending,
},
} satisfies ProjectionDefinition<'conversationContinuation', ContinuationState>
+5 -2
View File
@@ -209,7 +209,10 @@ export class SessionController extends TypertRemoteService {
this.stateController = new StateController(ctx, this.historyController)
this.webController = new WebController(ctx, this.historyController, (observation) => { this.promote(observation) })
this.listState = new ApiSessionList(ctx, this.listWorkSliceMs)
await this.commands.initialize()
ctx.fiber.assertActive()
await this.listState.initialize()
ctx.fiber.assertActive()
ctx.plugin(SessionFileReferences)
ctx.plugin(SessionMediaReferences)
ctx.plugin(SessionSkillCatalog)
@@ -464,7 +467,7 @@ export class SessionController extends TypertRemoteService {
@Remote('prompt')
async prompt(request: SessionPromptRequest, signal: AbortSignal): Promise<SessionPromptValue> {
signal.throwIfAborted()
if (!hasPromptContent(request.content)) {
if (request.content.length > 0 && !hasPromptContent(request.content)) {
throw new RemoteError('gateway/bad-request', 'prompt content must include non-whitespace text or an attachment', {})
}
const clientTimeZone = request.clientTimeZone === undefined
@@ -480,7 +483,7 @@ export class SessionController extends TypertRemoteService {
// The caller is recorded only when it is not the owner, so owner messages keep their exact source.
const principal = principalOf(this.ctx.invocation)
const source: MessageSource = {
kind: 'user',
kind: request.content.length === 0 ? 'retry' : 'user',
rpcId: request.requestId,
...(clientTimeZone === undefined ? {} : { clientTimeZone }),
...(principal === undefined ? {} : { principal }),
+7 -3
View File
@@ -8,7 +8,7 @@ import type {
import type { Branded } from '@deepseek-ai/dsh-brand'
import type { LlmAttemptId, MessageId } from '@deepseek-ai/dsh-llm/brand'
import type { LlmModelBadge, TextBlock } from '@deepseek-ai/dsh-llm'
import type { SessionId, SessionSeqCursor } from '@deepseek-ai/dsh-session/types'
import type { SessionId, SessionSeq, SessionSeqCursor } from '@deepseek-ai/dsh-session/types'
import type { SessionProjectionMap, SessionProjectionSummaryExcluded, SessionProjectionSummaryValues } from '@deepseek-ai/dsh-session-projection/types'
import type { Principal } from '@deepseek-ai/dsh-typert-protocol'
import type { JsonValue } from '@deepseek-ai/dsh-util-values'
@@ -16,6 +16,8 @@ import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types'
declare module '@deepseek-ai/dsh-session-projection/types' {
interface SessionProjectionMap {
/** Eligible latest failed turn/end for an empty prompt, or null. */
conversationContinuation: SessionSeq | null
/** Persisted facts used to summarize a Session without activating it. */
sessionListMetadata: SessionListMetadata
/**
@@ -320,11 +322,11 @@ export interface SessionForkValue {
/** Session prompt request. */
export interface SessionPromptRequest {
/** Client-minted identity persisted on the exact accepted user message. */
/** Client-minted identity persisted on the accepted inbox input, including empty continuation. */
readonly requestId: SessionRequestId
readonly sessionId: SessionId
readonly mode: 'queue' | 'steer'
/** At least one non-whitespace text part or attachment. */
/** Non-whitespace text or attachments; an empty array continues an eligible failed idle Session. */
readonly content: readonly PromptContentPart[]
readonly clientTimeZone?: string
}
@@ -396,6 +398,8 @@ declare module '@deepseek-ai/dsh-llm' {
* caller other than the owner, so an absent `principal` means the owner.
*/
'user-rpc': { kind: 'user'; rpcId: SessionRequestId; clientTimeZone?: string; principal?: Principal }
/** Empty retry user message with browser prompt correlation and caller metadata. */
'retry-rpc': { kind: 'retry'; rpcId: SessionRequestId; clientTimeZone?: string; principal?: Principal }
}
}
@@ -0,0 +1,162 @@
/** Complete-log continuation projection, including recovery and publication. */
import { Context } from '@deepseek-ai/cordis'
import SessionStore, { SessionId, SessionSeq, SessionLogOffset } from '@deepseek-ai/dsh-session'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { createAssistantMessage, createUserMessage } from '@deepseek-ai/dsh-llm'
import type { SessionEvent, TurnEndReason } from '@deepseek-ai/dsh-session/types'
import { expect, it, onTestFinished, vi } from 'vitest'
import { continuationProjectionDefinition as definition } from '../src/continuation.ts'
import { paginate } from '../src/history.ts'
import { continuationTurn as turn } from '../../../client/ui-conversation/tests/continuation-fixture.ts'
const failed = (code: string): TurnEndReason => ({ kind: 'error', error: { code, message: code } })
function fold(events: readonly SessionEvent[]) {
return events.reduce((state, event) => definition.apply(state, event), definition.init())
}
const events = (reason: TurnEndReason) => turn(reason).map(entry => entry.event)
it.each(['RATE_LIMIT', 'SERVER', 'TIMEOUT', 'TRANSPORT', 'EMPTY_RESPONSE', 'STREAM_CLOSED'])(
'offers a manual new turn after %s independently of automatic retries', (code) => {
expect(definition.wire.view(fold(events(failed(code))))).toBe(5)
},
)
it.each(['AUTH', 'QUOTA', 'ACCOUNT_QUOTA', 'MISSING_CREDENTIAL', 'INVALID_CREDENTIAL', 'UNKNOWN_MODEL',
'INVALID_REQUEST', 'CONTEXT_WINDOW_EXCEEDED', 'TOOL_ACTIVATION_FAILED', 'MALFORMED_RESPONSE', 'PI_AI_ERROR', 'UNKNOWN'])(
'leaves %s to its own recovery action', (code) => {
expect(definition.wire.view(fold(events(failed(code))))).toBeNull()
},
)
it.each<TurnEndReason>([
{ kind: 'completed' }, { kind: 'max-tokens' }, { kind: 'blocked' },
{ kind: 'interrupted' }, { kind: 'forked' }, { kind: 'aborted', reason: { kind: 'user' } },
])('leaves a $kind turn unchanged', (reason) => {
expect(definition.wire.view(fold(events(reason)))).toBeNull()
})
it('requires admitted human input and a failed settlement in the last step', () => {
const base = events(failed('TIMEOUT'))
expect(fold(base.filter(event => event.type !== 'user/message')).ending).toBeNull()
expect(fold(base.filter(event => event.type !== 'assistant/attempt')).ending).toBeNull()
const user = base.find(event => event.type === 'user/message')!
const replacement: SessionEvent<'user/message'> = { ...user,
surfaceOp: { op: 'replace', startSeq: SessionSeq(0), endSeq: SessionSeq(1) },
}
expect(fold(base.map(event => event === user ? replacement : event)).ending).toBeNull()
const injected: SessionEvent<'user/message'> = { ...user, data: createUserMessage({
content: [{ type: 'text', text: 'mode context' }], source: { kind: 'user-approval' },
}) }
expect(fold(base.map(event => event === user ? injected : event)).ending).toBeNull()
const prefix = base.slice(0, -1)
const step: SessionEvent<'step/start'> = { type: 'step/start', seq: SessionSeq(5), time: 0, data: { turn: 1, step: 2 } }
expect(fold([...prefix, step, base.at(-1)!]).ending).toBeNull()
const success: SessionEvent<'assistant/message'> = { type: 'assistant/message', seq: SessionSeq(5), time: 0,
surfaceOp: 'append', data: { turn: 1, step: 1, stream: [], message: createAssistantMessage({
content: [{ type: 'text', text: 'done' }], source: { provider: 'test', model: 'test' },
}) },
}
expect(fold([...prefix, success, base.at(-1)!]).ending).toBeNull()
})
it('keeps unrelated events and repeated settlements reference-stable', () => {
const base = events(failed('SERVER'))
const state = fold(base.slice(0, -1))
expect(definition.apply(state, base[2]!)).toBe(state)
expect(definition.apply(state, base[3]!)).toBe(state)
expect(definition.apply(state, base[4]!)).toBe(state)
expect(definition.apply(definition.init(), base[1]!)).toBe(definition.init())
const reset = definition.apply(state, base[1]!)
expect(reset.failedAttempt).toBe(false)
})
it('restores a checkpoint plus suffix identically to full replay and retires on a new turn', () => {
const base = events(failed('SERVER'))
const prefix = fold(base.slice(0, 3))
const restored = definition.stateSchema.parse(JSON.parse(JSON.stringify(prefix)))
expect(base.slice(3).reduce((state, event) => definition.apply(state, event), restored)).toEqual(fold(base))
const ended = fold(base)
expect(definition.apply(ended, { type: 'turn/start', seq: SessionSeq(6), time: 1, data: { turn: 2 } }).ending).toBeNull()
expect(definition.wire.viewSchema.parse(ended.ending)).toBe(5)
expect(() => definition.stateSchema.parse({ ...ended, ending: -1 })).toThrow()
expect(() => definition.wire.viewSchema.parse('5')).toThrow()
})
it('publishes a complete-log result independently of the visible page and releases registration', async () => {
const ctx = new Context()
onTestFinished(() => ctx.fiber.dispose())
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
const fiber = await ctx.sessionProjections.register(definition)
const session = ctx.sessions.create(SessionId('continued'))
expect(ctx.sessionProjections.snapshot(session).values.conversationContinuation).toBeNull()
const history: SessionEvent[] = []
ctx.on('session/event', (_session, event) => { history.push(event) })
const changed = vi.fn<Parameters<typeof ctx.sessionProjections.onChanged>[0]>()
ctx.sessionProjections.onChanged(changed)
session.append('turn/start', { turn: 1 })
expect(changed).not.toHaveBeenCalled()
session.append('step/start', { turn: 1, step: 1 })
session.append('user/message', createUserMessage({ content: [{ type: 'text', text: 'task' }], source: { kind: 'user' } }), { surfaceOp: 'append' })
// A long failed turn exceeds the browser's 500-message page budget.
for (let index = 0; index < 600; index++) {
session.append('assistant/message', { turn: 1, step: index + 1, stream: [], message: createAssistantMessage({ content: [{ type: 'text', text: 'progress' }], source: { provider: 'test', model: 'test' } }) }, { surfaceOp: 'append' })
session.append('step/end', { turn: 1, step: index + 1 })
session.append('step/start', { turn: 1, step: index + 2 })
}
session.append('assistant/attempt', { turn: 1, step: 601, stream: [] })
const ending = session.append('turn/end', { turn: 1, reason: failed('SERVER') }).seq
const page = paginate(history, undefined, 500, ending, { minMessages: 50, minTurns: 2 })
expect(page.hasMore).toBe(true)
expect(page.events.some(event => event.type === 'turn/start')).toBe(false)
expect(ctx.sessionProjections.snapshot(session).values.conversationContinuation).toBe(ending)
expect(changed.mock.calls.map(([, key, value]) => [key, value])).toEqual([['conversationContinuation', null], ['conversationContinuation', ending]])
expect(ctx.sessionProjections.checkpoint(session).conversationContinuation)
.toEqual({ ver: 4, seq: ending, val: { admitted: false, failedAttempt: false, ending } })
session.append('turn/start', { turn: 2 })
expect(ctx.sessionProjections.snapshot(session).values.conversationContinuation).toBeNull()
expect(changed).toHaveBeenCalledTimes(3)
await fiber.dispose()
expect(ctx.sessionProjections.snapshot(session).values).not.toHaveProperty('conversationContinuation')
})
it('restores valid, absent and outdated checkpoints through the registry', async () => {
const ctx = new Context()
onTestFinished(() => ctx.fiber.dispose())
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.sessionProjections.register(definition)
const session = ctx.sessions.create(SessionId('restored'))
const log = events(failed('SERVER'))
const checkpoint = { conversationContinuation: { ver: 4, seq: SessionSeq(2), val: fold(log.slice(0, 3)) } }
const restore = (rows: typeof checkpoint | Record<string, never>, tail: readonly SessionEvent[], base: number) =>
ctx.sessionProjections.restore(rows, tail, SessionLogOffset(base), session.header, session.inheritedEventCount)
expect(restore(checkpoint, log.slice(3), 3).snapshot.values.conversationContinuation).toBe(5)
expect(restore({}, log, 0).snapshot.values.conversationContinuation).toBe(5)
const outdated = { conversationContinuation: { ...checkpoint.conversationContinuation, ver: 3 } }
expect(restore(outdated, log, 0).snapshot.values.conversationContinuation).toBe(5)
expect(() => restore(outdated, log.slice(3), 3)).toThrow('re-read from seq 0')
expect(() => restore({}, log.slice(3), 3)).toThrow('re-read from seq 0')
})
it('admits empty retry messages while ignoring empty ordinary and non-empty retry messages', () => {
const base = events(failed('SERVER'))
const input = base.find(event => event.type === 'user/message')!
const empty: SessionEvent<'user/message'> = { ...input, type: 'user/message', data: createUserMessage({
content: [], source: { kind: 'user' },
}) }
expect(fold(base.map(event => event === input ? empty : event)).ending).toBeNull()
const retry: SessionEvent<'user/message'> = { ...empty, data: createUserMessage({
content: [], source: { kind: 'retry', rpcId: 'retry' as import('../src/types.ts').SessionRequestId },
}) }
const nonEmpty: SessionEvent<'user/message'> = { ...retry, data: { ...retry.data,
content: [{ type: 'text', text: 'not an empty retry' }],
} }
expect(fold(base.map(event => event === input ? nonEmpty : event)).ending).toBeNull()
const replacement: SessionEvent<'user/message'> = { ...retry,
surfaceOp: { op: 'replace', startSeq: SessionSeq(0), endSeq: SessionSeq(1) },
}
expect(fold(base.map(event => event === input ? replacement : event)).ending).toBeNull()
expect(fold(base.map(event => event === input ? retry : event)).ending).toBe(5)
const admitted = definition.apply(definition.init(), retry)
expect(definition.apply(admitted, retry)).toBe(admitted)
})
@@ -0,0 +1,96 @@
/** Empty prompt admission over the real AgentLoop and the Session Remote owner. */
import { Context } from '@deepseek-ai/cordis'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit'
import { createUserMessage, LlmError } from '@deepseek-ai/dsh-llm'
import { SessionId } from '@deepseek-ai/dsh-session'
import { expect, it, onTestFinished } from 'vitest'
import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
import type { SessionPromptRequest, SessionRequestId } from '../src/types.ts'
import { createSessionTestRemote } from './test-remote.ts'
async function setup() {
const ctx = new Context()
onTestFinished(() => ctx.fiber.dispose())
await mountAgentLoopTestDependencies(ctx)
await ctx.plugin(AgentLoop, { agents: [] })
const fail = (): never => { throw new LlmError('busy', 'SERVER') }
const adapter = new MockAdapter([fail, fail, textResponse('done')])
ctx.effect(() => ctx.llm.registerAdapter(['mock'], adapter))
const remote = await createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'mock', model: 'mock' }), cwd: '/workspace' })
const agent = await ctx.agentLoop.create(SessionId('empty-prompt'), { provider: 'mock', model: 'mock' })
const request = (id: string, mode: SessionPromptRequest['mode'] = 'queue'): SessionPromptRequest => ({
sessionId: agent.id, requestId: id as SessionRequestId, content: [], mode,
})
return { ctx, remote, agent, adapter, request }
}
it('records empty retry user messages without duplicate requests', async () => {
const { remote, agent, adapter, request } = await setup()
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'original task' }], source: { kind: 'user' } }))
await agent.whenIdle()
const first = request('continue-1')
expect((await remote.prompt(first)).ok).toBe(true)
await agent.whenIdle()
expect(adapter.requests).toHaveLength(2)
expect((await remote.prompt(first)).ok).toBe(true)
await agent.whenIdle()
expect(adapter.requests).toHaveLength(2)
expect((await remote.prompt(request('continue-2'))).ok).toBe(true)
await agent.whenIdle()
expect(adapter.requests).toHaveLength(3)
const events = agent.session.snapshotEvents()
const messages = events.flatMap(event => event.type === 'user/message' && event.data.source.kind === 'user' ? [event.data] : [])
expect(messages).toHaveLength(1)
const retries = events.flatMap(event => event.type === 'user/message' && event.data.source.kind === 'retry' ? [event.data] : [])
expect(retries).toHaveLength(2)
expect(retries).toMatchObject([
{ content: [], source: { kind: 'retry', rpcId: 'continue-1' } },
{ content: [], source: { kind: 'retry', rpcId: 'continue-2' } },
])
const controls = events.flatMap(event => event.type === 'agent/inbox/spliced' ? event.data.inserted : [])
.filter(message => message.source.kind === 'retry')
expect(retries.map(retry => retry.id)).toEqual(controls.map(control => control.id))
expect(adapter.requests[1]!.messages.filter(message => message.role === 'user').map(message => message.content))
.toEqual([[{ type: 'text', text: 'original task' }], []])
expect(adapter.requests[2]!.messages.filter(message => message.role === 'user').map(message => message.content))
.toEqual([[{ type: 'text', text: 'original task' }], [], []])
expect(events.flatMap(event => event.type === 'turn/end' ? [event.data.reason.kind] : [])).toEqual(['error', 'error', 'completed'])
expect(events.filter(event => event.type === 'turn/start')).toHaveLength(3)
expect((await remote.prompt(request('after-completion'))).ok).toBe(false)
})
it('refuses empty fresh sessions, steering, queued human input and maintenance without waking work', async () => {
const { remote, agent, adapter, request } = await setup()
expect((await remote.prompt(request('empty-fresh'))).ok).toBe(false)
expect(adapter.requests).toHaveLength(0)
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'original task' }], source: { kind: 'user' } }))
await agent.whenIdle()
expect((await remote.prompt(request('empty-steer', 'steer'))).ok).toBe(false)
const pending = createUserMessage({ content: [{ type: 'text', text: 'queued' }], source: { kind: 'user' } })
agent.inbox.append('next-turn', pending)
expect((await remote.prompt(request('empty-queued'))).ok).toBe(false)
agent.inbox.clear()
agent.inject(pending)
expect((await remote.prompt(request('empty-steering'))).ok).toBe(false)
agent.inbox.clear()
await agent.runMaintenance(async () => {
expect((await remote.prompt(request('empty-maintenance'))).ok).toBe(false)
})
expect(adapter.requests).toHaveLength(1)
})
it('consumes injected context with the empty prompt', async () => {
const { ctx, remote, agent, adapter, request } = await setup()
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'original task' }], source: { kind: 'user' } }))
await agent.whenIdle()
agent.inject(createUserMessage({ content: [{ type: 'text', text: 'approval context' }], source: { kind: 'user-approval' } }))
agent.model.select({ provider: 'mock', model: 'changed' })
expect((await remote.prompt(request('empty-context'))).ok).toBe(true)
await agent.whenIdle()
expect(adapter.requests).toHaveLength(2)
expect(JSON.stringify(adapter.requests[1]!.messages)).toContain('approval context')
expect(adapter.requests[1]!.model).toBe('changed')
expect(agent.inbox.nextStep).toHaveLength(0)
expect(ctx.sessionProjections.snapshot(agent.session).values.conversationContinuation).not.toBeNull()
})
@@ -875,7 +875,7 @@ async function modelFor(ctx: Context, session: Session): Promise<AgentModel> {
}
describe('sessions.prompt synchronous rejection', () => {
it('rejects content without non-whitespace text or an attachment before delivery or Session events', async () => {
it('rejects whitespace-only text parts before delivery or Session events', async () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
@@ -925,7 +925,6 @@ describe('sessions.prompt synchronous rejection', () => {
})
const initialEvents = session.snapshotEvents()
const rejectedContent: readonly SessionPromptRequest['content'][] = [
[],
[{ type: 'text', text: '' }],
[{ type: 'text', text: ' \t\n' }, { type: 'text', text: '' }],
]
@@ -417,11 +417,16 @@ describe('session.history projections block', () => {
.toBe(false)
seedMessages(session, 1)
const changed = await iterator.next()
expect(changed).toMatchObject({
done: false,
value: { type: 'projection', changes: [{ key: 'sessionListMetadata' }] },
})
let changed = await iterator.next()
while (!changed.done && changed.value.type === 'projection'
&& !changed.value.changes.some(change => change.key === 'sessionListMetadata')) {
expect(changed.value.changes.map(change => change.key)).not.toContain('test/internal-count')
changed = await iterator.next()
}
if (changed.done || changed.value.type !== 'projection') throw new Error('control stream ended before its projection')
const keys = changed.value.changes.map(change => change.key)
expect(keys).toContain('sessionListMetadata')
expect(keys).not.toContain('test/internal-count')
abort.abort()
await iterator.return?.()
@@ -527,7 +532,7 @@ describe('session.list projections column', () => {
expect(excludedApply).not.toHaveBeenCalled()
})
it('carries every registered summary key, which is only its own list metadata when no other unit is registered', async () => {
it('carries list metadata and unavailable retry eligibility through registered summary keys', async () => {
const { ctx, session } = await harness(false)
seedMessages(session, 1)
const response = await (await remote(ctx)).list(request({}))
@@ -535,7 +540,8 @@ describe('session.list projections column', () => {
const row = response.value.items.find(item => item.sessionId === session.id)
expect(row?.projections?.kind).toBe('sequenced')
expect(Object.keys(row?.projections?.values ?? {})).toEqual([...ctx.sessionProjections.summaryKeys()])
expect(Object.keys(row?.projections?.values ?? {})).toEqual(['sessionListMetadata'])
expect(Object.keys(row?.projections?.values ?? {})).toEqual(['conversationContinuation', 'sessionListMetadata'])
expect(row?.projections?.values.conversationContinuation).toBeNull()
})
it('serves the summary projection hints from the cache with zero log loads', async () => {
@@ -754,11 +760,12 @@ describe('Session control projection frames', () => {
iterable: AsyncIterable<SessionControlFrame>,
count: number,
abort: AbortController,
keys: readonly string[],
): Promise<SessionControlFrame[]> {
const frames: SessionControlFrame[] = []
for await (const frame of iterable) {
frames.push(frame)
if (frames.filter(candidate => candidate.type === 'projection').length >= count) abort.abort()
if (frames.filter(candidate => candidate.type === 'projection' && candidate.changes.some(change => keys.includes(change.key))).length >= count) abort.abort()
}
return frames
}
@@ -772,7 +779,7 @@ describe('Session control projection frames', () => {
await new Promise(resolve => setTimeout(resolve, 0))
const abort = new AbortController()
const stream = proxy.control(abort.signal)
const collected = collect(stream, 3, abort)
const collected = collect(stream, 3, abort, ['test/last-user', 'sessionListMetadata'])
const now = vi.spyOn(Date, 'now').mockReturnValue(100)
seedMessages(session, 1)
@@ -789,6 +796,7 @@ describe('Session control projection frames', () => {
{
type: 'projection', sessionId: session.id, seq: 0, changes: [
{ key: 'test/last-user', val: { text: 'm0' } },
{ key: 'conversationContinuation', val: null },
{ key: 'sessionListMetadata', val: { blank: true, lastPromptAt: 100 } },
],
},
@@ -829,6 +837,7 @@ describe('Session control projection frames', () => {
value: {
type: 'projection', seq: 0, changes: [
{ key: 'test/last-user', val: { text: 'm0' } },
{ key: 'conversationContinuation', val: null },
{ key: 'sessionListMetadata', val: { blank: true, lastPromptAt: 100 } },
],
},
@@ -25,7 +25,8 @@
"src/list.ts",
"src/media-references.ts",
"src/archived-session-gate.ts",
"src/skill-catalog.ts"
"src/skill-catalog.ts",
"src/continuation.ts"
],
"references": [
{
@@ -126,6 +127,9 @@
},
{
"path": "../../session/working-directory"
},
{
"path": "../../util/brand"
}
]
}
+2 -2
View File
@@ -30,8 +30,8 @@
en: 382821ca3ffa60dd
zh: 9840ffa07c13082a
/deepseek-ai-dsh-client-ui-chat/turn-process-folding:
en: b0d806604bc17006
zh: 18dabe5dc2d0d419
en: 7cc6692b879aa500
zh: e924733c88b526c9
/deepseek-ai-dsh-client-ui-chat/grouped-rendering:
en: b1630d93a52f483e
zh: 59cb81ca50ecffc4
+2
View File
@@ -98,6 +98,8 @@ The completed-turn action footer follows the recorded Turn end. Its action row s
<a id="turn-process-folding"></a>
## Turn Process Folding
Empty `user/message` records with `source.kind: 'retry'` remain in Session history while Chat renders a compact continuation-request receipt instead of a user bubble. Ordinary empty user messages and retry messages containing content retain their normal presentation.
During uninterrupted following, local transcript and steering echoes remain mounted through Inbox acceptance and claim until the durable message arrives, without triggering tail following twice. Pending steering follows Inbox order across clients, using matching local echoes in place. Admitted local steering also suppresses matching stale Inbox rows until the claim projection arrives; steering without a locally tracked submission continues to follow the Inbox projection. After reconnect, Host-owned rows replace receipt-confirmed local echoes; a claim awaiting admission may briefly have no bubble.
When Chat ends with an open Turn control and that Turn has no visible input, the first local transcript echo precedes the control. Other echoes remain at the flow tail. The control and echoes share one keyed list, so arrival of the control preserves the echo's mounted identity. Durable inputs replace their matching echoes in the same render.
+2
View File
@@ -98,6 +98,8 @@ Chat 在 `MarkdownDelegateProvider.getTriggerProps` 接入处适配 Markdown 目
<a id="turn-process-folding"></a>
## 轮次过程折叠
带 `source.kind: 'retry'` 的空 `user/message` 记录保留在 Session 历史中,Chat 显示轻量的继续请求记录,不生成用户气泡。普通空用户消息与包含内容的重试消息保持正常展示。
正常在线时,本地 transcript 与 steering 回显在 Inbox 接受与领取期间保持挂载,直到持久消息到达,不会重复触发跟随底部。跨客户端的待处理 steering 遵循 Inbox 顺序,在匹配位置使用本地回显。已入档的本地 steering 还会排除匹配的旧 Inbox 行,直到领取投影到达;没有本地提交身份的 steering 仍按 Inbox 投影显示。重连后,Host 消息替代已有接收回执的本地回显;已领取但尚未入档时,气泡可能短暂消失。
Chat 末尾为进行中的 Turn 控制行,且该轮尚无可见输入时,第一条本地 transcript 回显显示在控制行前。其他回显保留在正文末尾。控制行与回显共用一个 keyed 列表,因此控制行到达时不会重新挂载回显。持久输入在同一次渲染中替换匹配的回显。
@@ -26,6 +26,17 @@
.header:hover { color: var(--dsw-alias-label-secondary); }
}
.icon { display: inline-flex; flex: none; color: inherit; }
.continuation {
display: flex;
align-items: center;
gap: 6px;
min-width: 0;
padding: 2px 0;
color: var(--dsw-alias-label-tertiary);
font-size: var(--dsh-content-font-size-secondary, 13px);
line-height: calc(20px + var(--dsh-content-font-delta-secondary, 0px));
overflow-wrap: anywhere;
}
.title { flex: 1; min-width: 0; overflow-wrap: anywhere; font-size: var(--dsh-content-font-size, 14px); }
.time { flex: none; margin-left: auto; color: inherit; font: var(--dsw-font-xxs-12); }
.chevron, .openChevron { flex: none; color: inherit; }
@@ -1,10 +1,10 @@
/** An independent, expandable notice explaining a non-human Turn trigger. */
/** Recorded Turn triggers and compact manual-continuation receipts. */
import { useId, useState, type ComponentType } from 'react'
import {
IconAgentPresetOutlineRegular, IconClockOutlineRegular, IconBranchOutlineRegular,
IconChevronDownOutlineRegular, IconContextInjectionOutlineRegular, IconCordisPluginOutlineRegular,
IconGoalOutlineRegular, IconGlobeOutlineRegular, IconPaperPlaneOutlineRegular, IconQueueOutlineRegular,
IconUsersOutlineRegular, type IconProps,
IconUsersOutlineRegular, IconPlayOutlineRegular, type IconProps,
} from '@deepseek-ai/dsh-client-ui-primitives'
import type { ChatNodeViewProps } from '../contract/slots.ts'
import { formatMessageClock } from './message-chrome.ts'
@@ -13,6 +13,7 @@ import { turnTriggerDetails, type TurnTriggerIcon } from './turn-trigger.ts'
import css from './TurnTriggerNodeView.module.css'
const TRIGGER_ICONS: Record<TurnTriggerIcon, ComponentType<IconProps>> = {
continue: IconPlayOutlineRegular,
request: IconContextInjectionOutlineRegular,
goal: IconGoalOutlineRegular,
agent: IconPaperPlaneOutlineRegular,
@@ -31,6 +32,12 @@ export function TurnTriggerNodeView({ node, t }: Pick<ChatNodeViewProps<'turn-tr
const bodyId = useId()
const details = turnTriggerDetails(node.data)
const TriggerIcon = TRIGGER_ICONS[details.icon]
if (details.compact) return (
<div className={css.continuation} data-generation-continuation>
<span className={css.icon} aria-hidden><TriggerIcon size={14} /></span>
<span>{t(details.title)}</span>
</div>
)
const date = new Date(node.data.time)
const time = formatMessageClock(node.data.time, t)
return (
@@ -3,7 +3,7 @@ import type { ContextMessageNode } from '../contract/snapshot.ts'
import type { ChatKey } from '../locale.ts'
/** Existing primitive glyph selected for a Turn trigger's source family. */
export type TurnTriggerIcon = 'agent' | 'github' | 'goal' | 'job' | 'plugin' | 'request' | 'schedule' | 'subagent' | 'team' | 'webhook'
export type TurnTriggerIcon = 'agent' | 'continue' | 'github' | 'goal' | 'job' | 'plugin' | 'request' | 'schedule' | 'subagent' | 'team' | 'webhook'
function record(value: unknown): Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {}
@@ -30,17 +30,21 @@ function subagentTitle(reason: unknown): ChatKey {
/**
* Describe a waking message using its recorded source.
* @param node - durable context, including the original notification body.
* @returns localized title key and source-family icon.
* @returns localized title, source-family icon, and compact presentation for continuation receipts.
*/
export function turnTriggerDetails(node: ContextMessageNode): {
title: ChatKey
icon: TurnTriggerIcon
compact?: true
} {
const source = record(node.source)
const kind = field(source, 'kind')
let title: ChatKey = 'message.trigger.request'
let icon: TurnTriggerIcon = 'request'
switch (kind) {
case 'retry':
if (node.content.length === 0) return { title: 'message.continuation.requested', icon: 'continue', compact: true }
break
case 'goal': {
title = 'message.trigger.goal'
icon = 'goal'
@@ -38,7 +38,7 @@ declare module '../contract/chat-nodes.ts' {
steering: ReferencedSteeringMessageNode
/** Non-user context injected into model history. */
context: ContextMessageNode
/** Non-human input that starts a Turn. */
/** Recorded notification or manual continuation that starts a Turn. */
'turn-trigger': ContextMessageNode
}
}
@@ -136,12 +136,16 @@ export const messageDefinition: ConversationNodeDefinition<MessageNode> = {
update: context => context.state,
buildViewNode: (context) => {
if (context.state === undefined) return null
const location = contextLocation(context)
if (context.state.kind === 'context' && context.start?.event.type === 'user/message'
&& context.start.event.data.source.kind === 'retry' && context.start.event.data.content.length === 0) {
return chatNode(context, 'turn-trigger', context.state.seq, context.state, { location, groupTree: 'input' })
}
const waking = context.state.kind === 'context'
&& context.start?.event.type === 'user/message'
&& context.state.waking === true
// Human input claimed for Step 1 opens an exchange; Notice-woken Turns and
// later steering stay in the current exchange, so they never fold earlier Turns.
const location = contextLocation(context)
const human = context.state.kind === 'user' || context.state.kind === 'steering'
const opensExchange = human && location.kind === 'step' && location.step.step === 1
return chatNode(
@@ -171,6 +171,7 @@ export const zh = {
'message.retry.active': '正在重试模型请求',
'message.retry.cancelled': '模型请求重试已取消',
'message.retry.started': '已重试模型请求',
'message.continuation.requested': '已请求继续生成',
'message.retry.scheduled': '等待重试模型请求',
'message.retry.status': '{label}({retry}/{maximum}) · {seconds}s',
'message.retry.delay': '重试延迟:',
@@ -380,6 +381,7 @@ export const en = {
'message.retry.active': 'Retrying model request',
'message.retry.cancelled': 'Model request retry cancelled',
'message.retry.started': 'Retried model request',
'message.continuation.requested': 'Requested to continue generation',
'message.retry.scheduled': 'Waiting to retry model request',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s',
'message.retry.delay': 'Retry delay: ',
@@ -586,6 +588,7 @@ export const ja = {
'message.retry.active': 'モデルリクエストを再試行中',
'message.retry.cancelled': 'モデルリクエストの再試行をキャンセルしました',
'message.retry.started': 'モデルリクエストを再試行しました',
'message.continuation.requested': '生成の続行をリクエストしました',
'message.retry.scheduled': 'モデルリクエストの再試行待ちです',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}秒',
'message.retry.delay': '再試行までの待機時間: ',
@@ -792,6 +795,7 @@ export const es = {
'message.retry.active': 'Reintentando solicitud de modelo',
'message.retry.cancelled': 'Reintento de solicitud de modelo cancelado',
'message.retry.started': 'Solicitud de modelo reintentada',
'message.continuation.requested': 'Se ha solicitado continuar la generación',
'message.retry.scheduled': 'Esperando para volver a intentar la solicitud de modelo',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s',
'message.retry.delay': 'Retraso de reintento: ',
@@ -998,6 +1002,7 @@ export const fr = {
'message.retry.active': 'Nouvelle tentative de demande de modèle',
'message.retry.cancelled': 'Nouvelle tentative de demande de modèle annulée',
'message.retry.started': 'Demande de modèle réessayée',
'message.continuation.requested': 'Suite de la génération demandée',
'message.retry.scheduled': 'En attente de réessayer la demande de modèle',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}',
'message.retry.delay': 'Délai de nouvelle tentative : ',
@@ -1204,6 +1209,7 @@ export const de = {
'message.retry.active': 'Modellanforderung wird erneut versucht',
'message.retry.cancelled': 'Wiederholungsversuch der Modellanforderung abgebrochen',
'message.retry.started': 'Modellanfrage erneut versucht',
'message.continuation.requested': 'Fortsetzung der Generierung angefordert',
'message.retry.scheduled': 'Warten auf erneuten Versuch der Modellanforderung',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s',
'message.retry.delay': 'Wiederholungsverzögerung: ',
@@ -1410,6 +1416,7 @@ export const ru = {
'message.retry.active': 'Повторный запрос модели',
'message.retry.cancelled': 'Повтор запроса модели отменен.',
'message.retry.started': 'Повторный запрос модели',
'message.continuation.requested': 'Запрошено продолжение генерации',
'message.retry.scheduled': 'Ожидание повторного запроса модели',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s',
'message.retry.delay': 'Задержка повтора: ',
@@ -1616,6 +1623,7 @@ export const pt = {
'message.retry.active': 'Tentando novamente a solicitação de modelo',
'message.retry.cancelled': 'Nova tentativa de solicitação de modelo cancelada',
'message.retry.started': 'Solicitação de modelo repetida',
'message.continuation.requested': 'Continuação da geração solicitada',
'message.retry.scheduled': 'Aguardando para tentar novamente a solicitação de modelo',
'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s',
'message.retry.delay': 'Atraso na nova tentativa: ',
@@ -626,6 +626,39 @@ describe('built-in conversation node Definitions', () => {
},
)
it.each(['replay', 'live', 'prepend'] as const)('presents empty retry receipts through %s while retaining other input', (mode) => {
const retry = { id: 'empty-retry', role: 'user', content: [], source: { kind: 'retry' } }
const before = [
at(1, 'agent/inbox/spliced', { target: 'next-turn', start: 0, inserted: [retry] }),
at(2, 'turn/start', { turn: 1 }),
at(3, 'agent/inbox/spliced', { target: 'next-turn', start: 0, removedCount: 1, inserted: [] }),
at(4, 'step/start', { turn: 1, step: 1 }),
]
const message = at(5, 'user/message', retry, { surfaceOp: 'append' })
const value = assembler(mode === 'replay' ? [...before, message] : mode === 'prepend' ? [message] : [], mode === 'prepend')
if (mode === 'live') for (const entry of [...before, message]) value.append(entry)
if (mode === 'prepend') value.prepend(before, false)
value.flush()
const current = snapshot(value)
const receipt = node(current, 'turn-trigger')
expect(receipt).toMatchObject({ anchorSeq: 5, groupTree: 'input', data: { content: [], source: { kind: 'retry' } } })
expect(current.order).toContain(receipt?.key)
expect(node(current, 'unknown')).toBeUndefined()
value.append(at(6, 'user/message', { ...retry, id: 'retry-with-content',
content: [{ type: 'text', text: 'retained context' }],
}, { surfaceOp: 'append' }))
value.append(at(7, 'user/message', { ...retry, id: 'ordinary-empty', source: { kind: 'user' } }, { surfaceOp: 'append' }))
value.append(at(8, 'developer/message', { turn: 1, step: 1,
message: { ...retry, id: 'developer-empty', role: 'developer' },
}, { surfaceOp: 'append' }))
value.flush()
expect(node(snapshot(value), 'context')?.data).toMatchObject({ content: [{ type: 'text', text: 'retained context' }] })
expect(node(snapshot(value), 'user')?.data).toMatchObject({ content: [], source: { kind: 'user' } })
expect(snapshot(value).nodes.values().find(candidate => candidate.anchorSeq === 8)?.data)
.toMatchObject({ content: [], source: { kind: 'retry' } })
})
it.each(['replay', 'live', 'prepend'] as const)('classifies waking Inbox messages through %s', (mode) => {
const notice = { ...textMessage('notice', 'scheduled work'), source: { kind: 'schedule' } }
const human = textMessage('human', 'user task')
@@ -24,6 +24,20 @@ function trigger(source: unknown): ChatNode<'turn-trigger'> {
}
describe('Turn trigger notices', () => {
it.each([
[en, 'Requested to continue generation'],
[zh, '已请求继续生成'],
])('shows an empty retry as a compact continuation receipt', (locale, title) => {
const node = trigger({ kind: 'retry' })
node.data.content = []
expect(turnTriggerDetails(node.data)).toEqual({ title: 'message.continuation.requested', icon: 'continue', compact: true })
const view = render(<TurnTriggerNodeView node={node} t={makeTranslate(locale)} />)
expect(view.getByText(title)).toBeDefined()
expect(view.queryByRole('button')).toBeNull()
expect(view.container.querySelector('[data-generation-continuation] svg')).not.toBeNull()
expect(view.container.querySelector('time')).toBeNull()
})
it.each([
[{ kind: 'schedule' }, 'schedule', 'Automation task'],
[{ kind: 'tool-jobs' }, 'job', 'Background task updated'],
@@ -35,6 +49,7 @@ describe('Turn trigger notices', () => {
[{ kind: 'webhook', provider: 'github' }, 'github', 'GitHub event received'],
[{ kind: 'webhook', provider: 'custom' }, 'webhook', 'External event received'],
[{ kind: 'custom-extension' }, 'request', 'Execution requested'],
[{ kind: 'retry' }, 'request', 'Execution requested'],
] as const)('presents the recorded %j source', (source, icon, title) => {
const node = trigger(source)
const details = turnTriggerDetails(node.data)
@@ -21,20 +21,29 @@
en: cc4dafd1aae02468
zh: be6b67724b7ac4a3
/deepseek-ai-dsh-client-ui-conversation/shell-and-standard-props:
en: c11cc27a337174f3
zh: a971ef53fa6046a2
en: 8994069b62a88825
zh: 262ace7ad9bd35b7
/deepseek-ai-dsh-client-ui-conversation/temporary-composer-entries:
en: 59cd63057dfb6eeb
zh: b2e2c86e810b7bb8
/deepseek-ai-dsh-client-ui-conversation/model-experience:
en: e0a05b73ba3e4318
zh: dc85ab8433bb4456
/deepseek-ai-dsh-client-ui-conversation/model-experience/kv-cache-effect:
en: 9f4e0da7c8addf88
zh: 1a33d9981af75643
en: 215e7ba838619b7b
zh: a311da3843709f90
/deepseek-ai-dsh-client-ui-conversation/model-experience/manual-continuation-request:
en: 6a7ae99570c9c007
zh: 26e86063e97d82c7
/deepseek-ai-dsh-client-ui-conversation/model-experience/manual-continuation-request/what-the-model-sees:
en: 017391d7ad0f9eb7
zh: 2693ed29d44b1164
/deepseek-ai-dsh-client-ui-conversation/model-experience/manual-continuation-request/token-effect:
en: 517c56dbd522c929
zh: 55fa3a02d026e36a
/deepseek-ai-dsh-client-ui-conversation/model-experience/manual-continuation-request/kv-cache-effect:
en: f8621bbc481c26ae
zh: 5be844989dc80803
/deepseek-ai-dsh-client-ui-conversation/known-limitations-and-deferred-work:
en: edd7248fc7e110fb
zh: 643e313c9585b73b
en: b3f74c35f88ab2fa
zh: 8492b314debd130c
/deepseek-ai-dsh-client-ui-conversation/known-limitations-and-deferred-work/dev-note:
en: e67f633dc6fe7773
zh: e88aeb617ffb74ea
+17 -2
View File
@@ -80,6 +80,12 @@ The composer measures its expanded control groups after size, content, visibilit
The context meter follows the [statistics-control radius](../../../docs/ui-radius.md#radius-scale).
An empty, idle ordinary Session composer offers a play action after `RATE_LIMIT`, `SERVER`, `TIMEOUT`, `TRANSPORT`, `EMPTY_RESPONSE`, or `STREAM_CLOSED` ends its latest turn. The failed turn must include admitted ordinary user input and a settled failed model attempt. Clicking submits `content: []` through the existing Session prompt API; drafts and attachments keep the Send action. A new balanced turn uses committed history and records an empty `user/message` with `source.kind: 'retry'`. Refusal or transport failure leaves the draft empty and reports the error through the ordinary submission lifecycle.
The Session API owns `conversationContinuation`, shared by Host admission and browser presentation. It restores eligibility from complete Session history and preserves it across repeated failed empty continuations, independently of loaded browser pages.
The composer exposes `retry(failureSeq)` for failed-generation recovery. The input bar reads `conversationContinuation` and `inbox` through the standard `useProjection` prop. User-facing text calls the action Continue generating.
The composer uses the shared [text-input focus policy](../ui-primitives/README.md#use-this-package) on mount, Session switching, and unlock. Identified phones and tablets require tapping the input; desktop devices retain automatic focus. On these mobile devices, a submission that empties the focused draft moves focus to the non-text composer card, dismissing the keyboard while retaining its navigation position. Rejected submissions, retained newer draft text, and another control already holding focus preserve focus. The [Lexical patch](../../../patches/lexical@0.49.0.patch) keeps caret scrolling in the same coordinate system as DOM geometry when a mobile keyboard pans the page.
The context-occupancy button shows a ring and percentage below the input card, after the Session statistics. Clicking it opens the token breakdown in a CSS-anchored panel bounded by the layout viewport, including when no statistics are shown; the button stays hidden until context usage and capacity are available. Browser zoom and panning move the panel with the page, so it may extend beyond the visual viewport. Outside the Hero, that row keeps one reading's height while it is empty, so statistics and context usage arriving later do not change the composer's height; the Hero shows no empty row.
@@ -191,11 +197,19 @@ Session title context gestures use the shared [context menu](../ui-context-menu/
<a id="model-experience"></a>
## Model Experience
None, as this package renders browser state and sends user-admitted inputs through Session Controller APIs without constructing model requests.
### Manual continuation request
#### What the model sees
The play action submits `content: []` through the existing Session prompt API. Ordinary Loop admission records an empty `user/message` with `source.kind: 'retry'`. Chat presents the empty retry as a compact continuation-request receipt. The adapter applies its ordinary message serialization; the action adds no localized or hidden continuation text. Pending injected context follows ordinary admission.
#### Token effect
The action adds no continuation text. Empty-message serialization and framing costs depend on the adapter. The request still incurs the ordinary cost of retained history, current prompt sections, tool declarations, and any newly admitted context.
#### KV Cache effect
None; Conversation assembly and browser input state do not alter provider-side prompt caching.
Serialization of the empty retry message depends on the adapter. Prefix reuse depends on the current model, prompt, tools, injected context, and provider cache policy.
## Known Limitations and Deferred Work
@@ -203,6 +217,7 @@ None; Conversation assembly and browser input state do not alter provider-side p
- **Only registered targets can render** — the shell deliberately has no implicit fallback target beyond the registered `chat` preference.
- **Factory occurrences inherit their render-position Session** — `conversation.content` does not accept an independently addressed Session; that requires a separate Session-provider capability.
- **Manual continuation uses a fixed product allowlist** — the supported failure codes are independent of the provider's configurable `retryableCodes`; changing automatic retry policy does not expand or reduce this action. `STREAM_CLOSED` permits an explicit new user turn even when the default policy does not retry it. That code can also identify a protocol violation, so another request is not guaranteed to recover.
- **Composer backdrop blur is verified only in Chromium** — with `will-change: transform` on the docked composer, descendant `backdrop-filter` still samples the transcript in Chromium; WebKit behavior has not been verified.
- **A failing Definition costs a full replay per publication** — after an incremental flush fails, the assembler replays the complete loaded window to keep the views correct. A Definition that fails on every update therefore replays the whole window on each publication until its owner fixes it ([window update paths](../../../docs/subsystems/conversation.md#window-update-paths)).
+17 -2
View File
@@ -80,6 +80,12 @@ root 作用域的 hoc Slot `conversation.hero.frame` 在所有阶段都包裹滚
上下文占用率入口遵循[统计控件圆角规则](../../../docs/ui-radius.zh.md#radius-scale)。
空闲且草稿为空的普通 Session,在最新轮次以 `RATE_LIMIT`、`SERVER`、`TIMEOUT`、`TRANSPORT`、`EMPTY_RESPONSE` 或 `STREAM_CLOSED` 结束后显示播放按钮。失败工作必须有已准入的普通用户输入和失败请求尝试。点击通过现有 Session prompt API 提交 `content: []`;已有草稿或附件仍使用发送按钮。新轮次正常闭合,使用已提交历史,并记录 `source.kind: 'retry'` 的空 `user/message`。请求被拒绝或传输失败时,草稿保持为空,错误沿用普通提交流程展示。
Session API 拥有 `conversationContinuation`,Host 准入和浏览器展示共用该投影。它从完整 Session 历史恢复资格,并在空输入继续再次失败时保留资格,不依赖浏览器已加载的历史分页。
composer 提供 `retry(failureSeq)` 处理生成失败后的恢复。输入栏通过标准 `useProjection` prop 读取 `conversationContinuation` 和 `inbox`。面向用户的操作文案为“继续生成”。
composer 在挂载、切换 Session 和解除锁定时使用共享的[文字输入框聚焦策略](../ui-primitives/README.zh.md#use-this-package)。识别出的手机和平板需要点击输入框;桌面设备保留自动聚焦。在这些移动设备上,提交清空正在聚焦的草稿后,焦点移到不接受文字输入的 composer 卡片,收起键盘并保留键盘导航位置。被拒绝的提交、保留的新草稿文字,以及已经聚焦的其他控件均保留原有焦点。移动端键盘平移页面时,[Lexical 补丁](../../../patches/lexical@0.49.0.patch)让光标滚动计算与 DOM 几何使用同一坐标系。
上下文占用按钮在输入卡片下方、会话统计右侧显示圆环和百分比。点击按钮可在受布局视口约束的 CSS 锚定面板中查看 token 构成,没有统计项时也可打开;上下文用量和容量尚不可用时,按钮保持隐藏。浏览器缩放和平移时面板随页面移动,因此可以超出视觉视口。Hero 之外,这一行为空时仍保留一项读数的高度,因此会话统计和上下文用量稍后到达不会改变 composer 的高度;Hero 不显示空行。
@@ -191,11 +197,19 @@ selector 必须是 owner currency 的纯函数。非 null 返回值作为 `match
<a id="model-experience"></a>
## 模型体验
无,因为本包渲染浏览器状态,并通过 Session Controller API 发送用户确认提交的输入,而不构造模型请求。
### 手动继续请求
#### 模型看到什么
播放按钮通过现有 Session prompt API 提交 `content: []`。普通 Loop 准入记录带 `source.kind: 'retry'` 的空 `user/message`。Chat 将空重试消息显示为轻量的继续请求记录。适配器按普通消息序列化处理;该操作不添加本地化或隐藏的继续文本。待注入上下文遵循普通准入流程。
#### Token 影响
该操作不增加继续文本。空消息的序列化及封装开销取决于适配器。请求仍承担保留历史、当前提示词、工具声明以及新准入上下文的正常输入成本。
#### KV Cache 影响
无;Conversation 组装和浏览器输入状态不会改变提供方侧的 prompt cache。
空重试消息的序列化取决于适配器。前缀复用取决于当前模型、提示词、工具、注入上下文及提供方缓存策略。
## 已知限制与暂缓事项
@@ -203,6 +217,7 @@ selector 必须是 owner currency 的纯函数。非 null 返回值作为 `match
- **只有已注册 target 可以渲染**——除已注册的 `chat` 偏好外,shell 刻意不提供隐式 fallback target。
- **Factory occurrence 继承渲染位置的 Session**——`conversation.content` 不接受独立寻址的 Session;该能力需要单独的 Session provider。
- **手动继续使用固定产品白名单**——支持的失败码独立于提供方可配置的 `retryableCodes`;修改自动重试策略不会扩展或缩小此操作的范围。即使默认策略不重试 `STREAM_CLOSED`,用户仍可明确发起新轮次。该错误码也可能表示协议违规,因此再次请求不保证能够恢复。
- **composer 内的毛玻璃只在 Chromium 中验证过**——docked composer 设置 `will-change: transform` 后,Chromium 中后代的 `backdrop-filter` 仍会采样背后的 transcript;WebKit 中的表现尚未验证。
- **出错的 Definition 让每次发布都完整回放**——增量 flush 失败后,assembler 回放已加载的完整窗口,以保持视图正确。若某个 Definition 在每次更新中都失败,在其 owner 修复前,每次发布都会回放整个窗口([Window 更新路径](../../../docs/subsystems/conversation.zh.md#window-update-paths))。
+3 -2
View File
@@ -59,7 +59,6 @@
"@deepseek-ai/dsh-api-session-controller": "workspace:*",
"@deepseek-ai/dsh-api-workspace-controller": "workspace:*",
"@deepseek-ai/dsh-attachment": "workspace:*",
"@deepseek-ai/dsh-brand": "workspace:*",
"@deepseek-ai/dsh-client-locale": "workspace:*",
"@deepseek-ai/dsh-client-file-upload": "workspace:*",
"@deepseek-ai/dsh-client-store": "workspace:*",
@@ -87,7 +86,6 @@
"react": "^18.2.0",
"@lexical/headless": "^0.49.0",
"react-dom": "^18.2.0",
"zod": "4.4.3",
"lexical": "^0.49.0",
"clsx": "^2.0.0",
"@lexical/utils": "^0.49.0",
@@ -99,6 +97,9 @@
"@deepseek-ai/dsh-client-shortcuts": "workspace:*",
"@deepseek-ai/dsh-client-product-analytics": "workspace:*",
"@deepseek-ai/dsh-message-quotes": "workspace:*",
"@deepseek-ai/dsh-session-projection": "workspace:*",
"@deepseek-ai/dsh-brand": "workspace:*",
"zod": "4.4.3",
"@deepseek-ai/dsh-client-ui-context-menu": "workspace:*"
},
"files": [
@@ -484,6 +484,7 @@ export function apply(ctx: Context, config: Config = Config({})): void {
retryFileUpload: undefined,
toggleCommandMenu: undefined,
stop: undefined,
retry: undefined,
hooks: {
stopShortcut,
busyEnter: submissionPolicy.busyEnter,
@@ -563,6 +564,7 @@ export function apply(ctx: Context, config: Config = Config({})): void {
})
},
stop: () => { stop(sessionId) },
retry: (failureSeq) => { inputHub.retry(sessionId, failureSeq) },
hooks: {
stopShortcut,
busyEnter: submissionPolicy.busyEnter,
@@ -352,6 +352,8 @@ export type InputEvent =
/** Enter submission with the current clipboard projection, its reference chips, its quotes, and its attachments. */
| {
readonly type: 'enter'
/** Explicit retry may submit an empty draft through the default sink. */
readonly allowEmpty?: boolean
readonly mode: InputSubmitMode
readonly draft: string
readonly occurrences: readonly Occurrence[]
@@ -14,7 +14,7 @@ import type {
} from '@deepseek-ai/dsh-client-ui-slots'
import type { SessionPendingInteraction } from '@deepseek-ai/dsh-client-ui-session/client'
import type {} from '@deepseek-ai/dsh-client-ui-layout/client'
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { SessionId, SessionSeq } from '@deepseek-ai/dsh-session/types'
import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types'
import type { ComposerBlock } from './composer-blocks.ts'
import type { DraftAttachmentId, InputActions, InputNotice, InputState } from './input.ts'
@@ -568,6 +568,11 @@ export interface ComposerBarInjected {
retryFileUpload: ((id: DraftAttachmentId) => void) | undefined
toggleCommandMenu: ((selection: EditSelection) => void) | undefined
stop: (() => void) | undefined
/**
* Submit empty input to retry the displayed failed generation.
* @param failureSeq - sequence of the displayed failed turn/end.
*/
retry: ((failureSeq: SessionSeq) => void) | undefined
hooks: {
/** Readable sequence while the fixed Stop command is registered. */
stopShortcut: ObservableSnapshot<readonly string[]>
@@ -387,8 +387,9 @@ export class SessionInputShell implements SessionInput {
* out from the machine; this method only feeds the event. Lock entry
* (adjudicating/submitting/sending) force-closes the transient layers: the
* popup dismisses and the menu tracks frozen.
* @param allowEmpty - explicitly admit empty continuation input through the default sink.
*/
submit(mode: InputSubmitMode = 'queue', source?: 'click' | 'enter'): void {
submit(mode: InputSubmitMode = 'queue', source?: 'click' | 'enter', allowEmpty = false): void {
if (this.disposed) return
const timestamp = Date.now()
let state: MessageSubmissionState | undefined
@@ -409,6 +410,7 @@ export class SessionInputShell implements SessionInput {
}
this.dispatchRun({
type: 'enter',
...allowEmpty ? { allowEmpty: true } : {},
mode,
draft: this.projection.clipboardText,
occurrences: [...this.projection.occurrences],
@@ -726,6 +728,10 @@ export class SessionInputShell implements SessionInput {
})
const send = (text: string): void => {
if (this.dead(attempt)) return
if (text === '' && draft !== '' && attachmentIds.length === 0) {
this.settleSink(attempt, Promise.resolve({ kind: 'success' }))
return
}
this.settleSink(attempt, this.deps.defaultSink(text, attachmentIds, mode, attempt.signal, () => { this.acceptSink(attempt) }))
}
if (!(prompt instanceof Promise)) { send(prompt); return }
@@ -11,7 +11,7 @@ import type { Context } from '@deepseek-ai/cordis'
import type {
ISessions, SessionBinding, SessionFace,
} from '@deepseek-ai/dsh-api-session-controller/client'
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { SessionId, SessionSeq } from '@deepseek-ai/dsh-session/types'
import type { TranslateNS } from '@deepseek-ai/dsh-client-locale/client'
import type { InboxState } from '@deepseek-ai/dsh-agent/types'
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent/types'
@@ -207,6 +207,29 @@ export class InputHub implements SessionInputResolver {
return this.shell(id)
}
/**
* Submit empty input to retry a failed generation through the ordinary composer. Stale
* failures, active work, and drafts keep their current input unchanged.
* @param id - retained ordinary Session identity.
* @param failureSeq - failed turn/end sequence the displayed button addresses.
*/
retry(id: SessionId, failureSeq: SessionSeq): void {
const binding = this.sessions().binding(id)
if (binding === undefined
|| binding.session.projections.faceOf('conversationContinuation').getSnapshot() !== failureSeq) return
const session = binding.session.getSnapshot()
const shell = this.shellFor(binding)
const input = shell.snapshot
const inbox = binding.session.projections.faceOf('inbox').getSnapshot() as InboxState | undefined
if (session.running || session.removed || session.openState !== 'open' || session.subagent !== null
|| session.pendingSubmissions.length > 0 || input.phase !== 'plain'
|| input.draft.trim() !== '' || input.attachmentIds.length > 0
|| (inbox?.['next-turn'].length ?? 0) > 0
|| inbox?.['next-step'].some(message => message.source.kind === 'user')
|| this.conversation().blocks.storeFor(id).getSnapshot() !== undefined) return
shell.submit('queue', 'click', true)
}
/**
* Query file intake without creating a Session input.
* @param id - target Session.
@@ -251,7 +274,9 @@ export class InputHub implements SessionInputResolver {
signal: AbortSignal,
accept: () => void,
): Promise<SubmitOutcome> {
if (text === '' && attachmentIds.length === 0) return Promise.resolve({ kind: 'success' })
if (text === '' && attachmentIds.length === 0) {
return session.prompt([], mode, signal).then(result => result.ok ? { kind: 'success' } : { kind: 'error' })
}
return this.conversation().sendSession(session, text, attachmentIds, mode, signal, accept)
}
@@ -144,7 +144,7 @@ export class SubmitMachine {
return [{ type: 'begin-submit', attempt, claim: this.claim, args: argsAfter(draft, this.claim.token) }]
}
const trimmed = draft.trim()
if (trimmed === '' && attachmentIds.length === 0) return []
if (trimmed === '' && attachmentIds.length === 0 && ev.allowEmpty !== true) return []
const attempt = this.beginAttempt(mode, draft, occurrences, quotes, attachmentIds, submission)
if (trimmed.startsWith('/')) {
this.phase = 'adjudicating'
@@ -27,6 +27,7 @@ export const zh = {
'input.file': '文件',
'input.stop': '停止生成',
'input.send': '发送消息',
'input.continue': '继续生成',
'input.sending': '正在发送消息',
'input.send.queue': '排队发送',
'input.send.steer': '插话发送',
@@ -421,6 +422,7 @@ export const en = {
'input.file': 'File',
'input.stop': 'Stop generating',
'input.send': 'Send message',
'input.continue': 'Continue generating',
'input.sending': 'Sending message',
'input.send.queue': 'Queue message',
'input.send.steer': 'Steer message',
@@ -814,6 +816,7 @@ export const ja = {
'input.file': 'ファイル',
'input.stop': '生成を停止',
'input.send': 'メッセージを送信',
'input.continue': '生成を続ける',
'input.sending': 'メッセージを送信中',
'input.send.queue': 'メッセージをキューに追加',
'input.send.steer': '実行中の指示にメッセージを追加',
@@ -1205,6 +1208,7 @@ export const es = {
'input.file': 'Archivo',
'input.stop': 'Detener generación',
'input.send': 'Enviar mensaje',
'input.continue': 'Continuar generando',
'input.sending': 'Enviando mensaje',
'input.send.queue': 'mensaje de cola',
'input.send.steer': 'Redirigir mensaje',
@@ -1598,6 +1602,7 @@ export const fr = {
'input.file': 'Fichier',
'input.stop': 'Arrêter la génération',
'input.send': 'Envoyer le message',
'input.continue': 'Continuer la génération',
'input.sending': 'Envoi du message',
'input.send.queue': "Message de file d'attente",
'input.send.steer': 'Guider avec ce message',
@@ -1991,6 +1996,7 @@ export const de = {
'input.file': 'Datei',
'input.stop': 'Generierung stoppen',
'input.send': 'Nachricht senden',
'input.continue': 'Generierung fortsetzen',
'input.sending': 'Nachricht wird gesendet',
'input.send.queue': 'Warteschlangennachricht',
'input.send.steer': 'Mit Nachricht lenken',
@@ -2384,6 +2390,7 @@ export const ru = {
'input.file': 'Файл',
'input.stop': 'Остановить генерацию',
'input.send': 'Отправить сообщение',
'input.continue': 'Продолжить генерацию',
'input.sending': 'Отправка сообщения',
'input.send.queue': 'Сообщение в очереди',
'input.send.steer': 'Направить сообщение',
@@ -2777,6 +2784,7 @@ export const pt = {
'input.file': 'Arquivo',
'input.stop': 'Parar geração',
'input.send': 'Enviar mensagem',
'input.continue': 'Continuar gerando',
'input.sending': 'Enviando mensagem',
'input.send.queue': 'Mensagem de fila',
'input.send.steer': 'Orientar com mensagem',
@@ -416,6 +416,11 @@
transform: translateY(-2px);
}
/* Solid artwork uses a smaller footprint than the thin send arrow. */
.continueIcon {
transform: scale(1.5);
}
@media (hover: hover) {
.primary:hover:not(:disabled) {
background: var(--dsw-alias-button-info-hover);
@@ -17,7 +17,7 @@ import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useStat
import type { ChangeEvent, KeyboardEvent, MouseEvent } from 'react'
import clsx from 'clsx'
import {
focusWithoutRing, IconPlusOutlineMedium, IconWarningOutlineRegular, isMobileDevice, Toast, Tooltip,
focusWithoutRing, IconPlusOutlineMedium, IconTriangleRightFillRegular, IconWarningOutlineRegular, isMobileDevice, Toast, Tooltip,
} from '@deepseek-ai/dsh-client-ui-primitives'
// Type-only: the `plan` projection key merge (the TodoDock posture — the
// composer reads a host-computed value; the domain owns the key).
@@ -46,7 +46,7 @@ export type InputBarProps = ComposerBarProps
export const InputBar = memo(function InputBar({
useSession, useInput, inputActions, keyboard, addFiles, removeAttachment, resolveDraftAttachments,
retryFileUpload,
toggleCommandMenu, stop, t,
toggleCommandMenu, stop, retry, t,
renderSlot, useBusyEnter, useFileUploads, useNotices, useLexicon, useMenuLauncher, useStopShortcut,
useAccess,
useProjection, sessionId, variant, disabled: inert = false, blocked,
@@ -70,6 +70,14 @@ export const InputBar = memo(function InputBar({
useEffect(() => { setActivity(false) }, [sessionId])
const promptError = useSession(s => s.promptError) ?? null
const running = useSession(s => s.running) ?? false
const retryableFailure = useProjection('conversationContinuation') ?? undefined
const pendingHumanInput = useProjection('inbox', inbox =>
inbox?.['next-step'].some(message =>
typeof message === 'object' && message !== null && 'source' in message
&& typeof message.source === 'object' && message.source !== null && 'kind' in message.source
&& message.source.kind === 'user') ?? false)
const historyOpen = useSession(s => s.openState === 'open') ?? false
const submissionPending = useSession(s => s.pendingSubmissions.length > 0) ?? false
const subagent = useSession(s => s.subagent) ?? null
const removed = useSession(s => s.removed) ?? false
// Plan mode swaps the composer placeholder (the projection is the folded
@@ -355,8 +363,12 @@ export const InputBar = memo(function InputBar({
// exposes Stop independently, and so does a running session while a
// message waits for the Host.
const primaryStops = running && subagent === null && !sending && (empty || blocked !== undefined)
const primaryRetries = !running && subagent === null && empty && retryableFailure !== undefined
&& !pendingHumanInput && historyOpen && !submissionPending && !disabled && input.queue.length === 0
&& input.phase === 'plain' && retry !== undefined
// Disabled native buttons may omit mouseleave; their tooltip must close from state.
const primaryDisabled = primaryStops ? stopAction === undefined : empty || disabled || machineBusy || uploadsPending
const primaryDisabled = primaryStops ? stopAction === undefined
: (!primaryRetries && empty) || disabled || machineBusy || uploadsPending
const interruptible = running && (continuable || (sending && subagent === null))
const primarySubmitMode = resolveSubmitMode(busyEnter, running, 'enter', steeringAvailable)
const plainMessageDraft = !empty && input?.phase === 'plain' && !draft.trimStart().startsWith('/')
@@ -364,14 +376,20 @@ export const InputBar = memo(function InputBar({
? t('input.stop')
: sending
? t('input.sending')
: running && steeringAvailable && !disabled && !uploadsPending && plainMessageDraft
? t(primarySubmitMode === 'steer' ? 'input.send.steer' : 'input.send.queue')
: t('input.send')
: primaryRetries
? t('input.continue')
: running && steeringAvailable && !disabled && !uploadsPending && plainMessageDraft
? t(primarySubmitMode === 'steer' ? 'input.send.steer' : 'input.send.queue')
: t('input.send')
const onPrimary = (): void => {
if (primaryStops) {
stopAction?.()
return
}
if (primaryRetries) {
retry(retryableFailure)
return
}
if (keyboard === undefined) return // absent machine: the button is disabled
/* v8 ignore next -- defensive: the primary button is disabled for empty, disabled, and pending-upload states. */
if (!empty && !disabled && !machineBusy && !uploadsPending) keyboard.submit(primarySubmitMode, 'click')
@@ -551,6 +569,8 @@ export const InputBar = memo(function InputBar({
<circle cx="8" cy="8" r="6" fill="none" stroke="currentColor" strokeOpacity="0.35" strokeWidth="2" />
<path d="M8 2a6 6 0 0 1 6 6" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
</svg>
) : primaryRetries ? (
<IconTriangleRightFillRegular size={16} className={css.continueIcon} />
) : (
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden>
<path d="M8.3125 0.980183C8.66767 1.0531 8.97902 1.20418 9.2627 1.43233C9.48724 1.61297 9.73029 1.85793 9.97949 2.10714L14.707 6.83468L13.293 8.24874L9 3.95577V15.0417H7V3.95577L2.70703 8.24874L1.29297 6.83468L6.02051 2.10714C6.26971 1.85793 6.51277 1.61297 6.7373 1.43233C6.97662 1.23986 7.28445 1.04402 7.6875 0.980183C7.8973 0.947006 8.1031 0.95516 8.3125 0.980183Z" fill="currentColor" />
+2 -2
View File
@@ -1,4 +1,4 @@
/** Host registration for browser conversation preferences. */
/** Browser conversation preferences. */
import type {} from '@deepseek-ai/dsh-settings'
import type { Volatile, Context } from '@deepseek-ai/cordis'
@@ -24,7 +24,7 @@ export const Config = z.object({
[BUSY_ENTER_FIELD]: ConversationSettingsFields[BUSY_ENTER_FIELD].volatile(),
})
/** Host preferences are consumed through the configuration form projection.
/** Register browser conversation preferences.
* @param ctx Plugin context used for optional settings presentation.
*/
export function apply(ctx: Context): void {
@@ -7,6 +7,7 @@ import { registerComposerKeymap } from '../src/client/input/editor/keymap.ts'
import { createSnapshotStore } from '@deepseek-ai/dsh-client-store'
import { describe, expect, it, onTestFinished, vi } from 'vitest'
import type { CommandContribution, CommandUiContract } from '@deepseek-ai/dsh-client-ui-commands/client'
import type { SessionRequestId } from '@deepseek-ai/dsh-api-session-controller/types'
import type { ISession, SessionReference } from '@deepseek-ai/dsh-api-session-controller/client'
import { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'
import * as messageQuotes from '@deepseek-ai/dsh-message-quotes/client'
@@ -24,6 +25,10 @@ import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types'
import { createConversationStore } from '../src/client/stores.ts'
import type { SessionInputShell } from '../src/client/input/facade.ts'
import { RemoteError } from '@deepseek-ai/dsh-client-test-runtime'
import { SessionSeq } from '@deepseek-ai/dsh-session/types'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import type { InboxWireState } from '@deepseek-ai/dsh-agent/types'
import { continuationTurn } from './continuation-fixture.ts'
declare module '@deepseek-ai/dsh-client-ui-slots' {
interface SlotMap {
@@ -161,6 +166,125 @@ async function bench(renderQuote = false) {
}
describe('Conversation inject API', () => {
it.each(['zh', 'en'])('submits empty continuation input in the %s locale', async (locale) => {
const b = await bench()
onTestFinished(() => b.runtime.dispose())
await b.runtime.sessions.replaceEvents(ROOT, continuationTurn({ kind: 'error', error: { code: 'SERVER', message: 'busy' } }))
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(5))
const composer = b.composerApi(ROOT)
b.runtime.ctx.locale.setLocale(locale)
const pending = Promise.withResolvers<Awaited<ReturnType<ISession['prompt']>>>()
onTestFinished(() => { pending.resolve({ ok: true, value: { accepted: true } }) })
b.sessionFake.prompt.mockImplementationOnce(() => pending.promise)
composer.retry!(SessionSeq(5))
composer.retry!(SessionSeq(5))
expect(composer.keyboard!.snapshot.phase).toBe('sending')
await vi.waitFor(() => { expect(b.sessionFake.prompt).toHaveBeenCalledOnce() })
expect(b.sessionFake.prompt.mock.calls[0]?.[0]).toEqual([])
expect(b.sessionFake.prompt.mock.calls[0]?.[1]).toBe('queue')
pending.resolve({ ok: true, value: { accepted: true } })
await vi.waitFor(() => { expect(composer.keyboard!.snapshot.phase).toBe('plain') })
expect(composer.keyboard!.snapshot.draft).toBe('')
})
it('rechecks the addressed failure, draft, and live activity before continuing', async () => {
const b = await bench()
onTestFinished(() => b.runtime.dispose())
await b.runtime.sessions.replaceEvents(ROOT, continuationTurn({ kind: 'error', error: { code: 'TIMEOUT', message: 'timeout' } }))
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(5))
const composer = b.composerApi(ROOT)
const input = b.inputApi(ROOT)
composer.retry!(SessionSeq(1))
input.actions.setDraft('Keep my new instruction')
composer.retry!(SessionSeq(5))
expect(input.state.getSnapshot().draft).toBe('Keep my new instruction')
input.actions.setDraft('')
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.running = true })
composer.retry!(SessionSeq(5))
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.running = false })
await b.runtime.sessions.appendEvent(ROOT, {
type: 'event', event: { type: 'turn/start', seq: SessionSeq(6), time: 1, data: { turn: 2 } },
})
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', null)
composer.retry!(SessionSeq(5))
expect(input.state.getSnapshot().draft).toBe('')
expect(b.sessionFake.prompt).not.toHaveBeenCalled()
})
it('keeps continuation available with injected mode context but excludes pending human steering', async () => {
const b = await bench()
onTestFinished(() => b.runtime.dispose())
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(5))
const composer = b.composerApi(ROOT)
const context = { id: 'context', role: 'user', content: [{ type: 'text', text: 'approval policy context' }], source: { kind: 'user-approval' } }
const inbox: InboxWireState = { 'next-turn': [], 'next-step': [context] }
await b.runtime.sessions.setProjection(ROOT, 'inbox', inbox)
const user = createUserMessage({ content: [{ type: 'text', text: 'new instruction' }], source: { kind: 'user' } })
await b.runtime.sessions.setProjection(ROOT, 'inbox', { ...inbox, 'next-step': [context, user] })
composer.retry!(SessionSeq(5))
expect(b.sessionFake.prompt).not.toHaveBeenCalled()
await b.runtime.sessions.setProjection(ROOT, 'inbox', inbox)
composer.retry!(SessionSeq(5))
await vi.waitFor(() => { expect(b.sessionFake.prompt).toHaveBeenCalledOnce() })
expect(b.sessionFake.prompt.mock.calls[0]?.[0]).toEqual([])
})
it.each(['next-turn', 'pending', 'block', 'attachment', 'subagent', 'removed', 'closed'] as const)(
'rejects a stale continuation click after %s changes', async (condition) => {
const b = await bench()
onTestFinished(() => b.runtime.dispose())
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(5))
const composer = b.composerApi(ROOT)
switch (condition) {
case 'pending':
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.pendingSubmissions = [{ requestId: 'pending' as SessionRequestId, placement: 'transcript', time: 0, text: 'newer message', attachments: [] }] })
break
case 'next-turn':
await b.runtime.sessions.setProjection(ROOT, 'inbox', { 'next-turn': [createUserMessage({ content: [{ type: 'text', text: 'queued' }], source: { kind: 'user' } })], 'next-step': [] })
break
case 'block':
b.runtime.ctx.conversation.blocks.set(ROOT, { reason: 'Choose a model' })
break
case 'attachment':
expect(composer.addFiles?.([new File([Uint8Array.of(1)], 'draft.pdf', { type: 'application/pdf' })])).toBeNull()
break
case 'subagent':
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.subagent = { address: { parentSessionId: ROOT, childSessionId: ROOT, mode: 'continuable' } } })
break
case 'removed':
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.removed = true })
break
case 'closed':
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.openState = 'error' })
break
}
const before = b.inputApi(ROOT).state.getSnapshot().draft
composer.retry!(SessionSeq(5))
expect(b.inputApi(ROOT).state.getSnapshot().draft).toBe(before)
expect(b.sessionFake.prompt).not.toHaveBeenCalled()
},
)
it.each(['refused', 'failed'] as const)('keeps continuation input empty and exposes submission failure when %s', async (outcome) => {
const b = await bench()
onTestFinished(() => b.runtime.dispose())
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(5))
const composer = b.composerApi(ROOT)
if (outcome === 'refused') b.sessionFake.prompt.mockImplementationOnce(async () => {
const error = new RemoteError('gateway/internal', 'request refused', {})
await b.runtime.sessions.updateSessionSnapshot(ROOT, (state) => { state.promptError = { op: 'send', error } })
return { ok: false, error }
})
else b.sessionFake.prompt.mockRejectedValueOnce(new Error('connection lost'))
composer.retry!(SessionSeq(5))
await vi.waitFor(() => { expect(b.sessionFake.prompt).toHaveBeenCalledOnce(); expect(composer.keyboard!.snapshot.phase).toBe('plain') })
expect(composer.keyboard!.snapshot.draft).toBe('')
if (outcome === 'refused') expect(b.runtime.sessions.binding(ROOT)!.session.getSnapshot().promptError?.error.message).toBe('request refused')
else expect(composer.hooks.notices.getSnapshot()).toMatchObject({ level: 'error', text: 'connection lost' })
composer.retry!(SessionSeq(5))
await vi.waitFor(() => { expect(b.sessionFake.prompt).toHaveBeenCalledTimes(2) })
})
it('renders literal quote text through the actual Factory and keyed node registration', async () => {
const b = await bench(true)
onTestFinished(() => b.runtime.dispose())
@@ -1,17 +1,22 @@
import SessionStore from '@deepseek-ai/dsh-session'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { Context } from '@deepseek-ai/cordis'
import { describe, expect, it } from 'vitest'
import { describe, expect, it, onTestFinished } from 'vitest'
import * as HostPlugin from '../src/index.ts'
import { liveConfig, omitsGeneratedPage } from '../../../settings/settings/tests/live-config.ts'
import { plainConfig } from '../../../settings/settings/src/schema.ts'
import {
DEFAULT_BUSY_ENTER_BEHAVIOR, Config, apply,
DEFAULT_BUSY_ENTER_BEHAVIOR,
} from '@deepseek-ai/dsh-client-ui-conversation'
describe('ui-conversation host', () => {
it('registers, validates, and disposes the durable busy-Enter preference', async () => {
const ctx = new Context()
const configuration = await liveConfig(ctx, { Config, apply })
onTestFinished(() => ctx.fiber.dispose())
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
const configuration = await liveConfig(ctx, HostPlugin)
const { fiber } = configuration
expect(plainConfig(configuration.fiber.effectiveConfig)).toEqual({ busyEnter: DEFAULT_BUSY_ENTER_BEHAVIOR })
await configuration.update({ busyEnter: 'steer' })
@@ -21,4 +26,9 @@ describe('ui-conversation host', () => {
})
})
it('keeps its own instance off the generated Settings pages', () => omitsGeneratedPage(ctx => ctx.plugin(HostPlugin)))
it('keeps its own instance off the generated Settings pages', () => omitsGeneratedPage(async (ctx) => {
onTestFinished(() => ctx.fiber.dispose())
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
return ctx.plugin(HostPlugin)
}))
@@ -0,0 +1,28 @@
/** Admitted input and a settled turn for manual-continuation tests. */
import type { SessionEvent } from '@deepseek-ai/dsh-session/types'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import { SessionSeq } from '@deepseek-ai/dsh-session/types'
import type { TurnEndReason } from '@deepseek-ai/dsh-session/types'
/**
* Build one settled turn with ordinary user input.
* @param reason - recorded turn ending.
* @param number - turn number and corresponding event offset.
* @returns ordered durable entries.
*/
export function continuationTurn(reason: TurnEndReason, number = 1): { type: 'event'; event: SessionEvent }[] {
const offset = (number - 1) * 6
return [
{ type: 'event', event: { type: 'turn/start', seq: SessionSeq(offset), time: 0, data: { turn: number } } },
{ type: 'event', event: { type: 'step/start', seq: SessionSeq(offset + 1), time: 0, data: { turn: number, step: 1 } } },
{ type: 'event', event: {
type: 'user/message', seq: SessionSeq(offset + 2), time: 0, surfaceOp: 'append',
data: createUserMessage({ content: [{ type: 'text', text: 'task' }], source: { kind: 'user' } }),
} },
{ type: 'event', event: {
type: 'assistant/attempt', seq: SessionSeq(offset + 3), time: 0, data: { turn: number, step: 1, stream: [] },
} },
{ type: 'event', event: { type: 'step/end', seq: SessionSeq(offset + 4), time: 0, data: { turn: number, step: 1 } } },
{ type: 'event', event: { type: 'turn/end', seq: SessionSeq(offset + 5), time: 0, data: { turn: number, reason } } },
]
}
@@ -26,7 +26,7 @@ import type { SessionListState, SessionSnapshot } from '@deepseek-ai/dsh-api-ses
import type { ContextPressureProjection } from '@deepseek-ai/dsh-token-meter/client'
import { zh as commonZh } from '@deepseek-ai/dsh-client-locale/src/locales/zh.ts'
import type { Context } from '@deepseek-ai/cordis'
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { SessionId, SessionSeq } from '@deepseek-ai/dsh-session/types'
import type { SubmitOutcome } from '../src/client/contract/input.ts'
import { SessionInputShell } from '../src/client/input/facade.ts'
import { $replaceDetectSpanWithText, $selectDetectSpan } from '../src/client/input/editor/span-map.ts'
@@ -81,6 +81,7 @@ interface BenchOptions {
}
draft?: string
running?: boolean
retryableFailure?: SessionSeq
subagent?: Exclude<SessionSnapshot['subagent'], null>
disabled?: boolean
inert?: boolean
@@ -161,6 +162,7 @@ function bench(over?: BenchOptions) {
if (over?.draft !== undefined && over.draft !== '') shell.setDraft(over.draft)
if (over?.attachments !== undefined) shell.addAttachments(over.attachments.map(attachment => attachment.id))
const stop = vi.fn()
const retry = vi.fn()
const removeAttachment = vi.fn((id: DraftAttachmentId) => { shell.removeAttachment(id) })
const menuLauncher = createSnapshotStore<string | null>(over?.commandMenuOpen === true ? 'command' : null)
const busyEnter = createSnapshotStore<'queue' | 'steer'>(over?.busyEnter ?? 'queue')
@@ -197,12 +199,14 @@ function bench(over?: BenchOptions) {
...allowAllAccess,
useContextMenu: contextMenuHook(),
useAccess: endpoint => !(over?.deniedEndpoints ?? []).includes(endpoint),
useProjection: ((key: string, selector?: (v: unknown) => unknown) =>
(selector ?? (v => v))(key === 'plan'
useProjection: ((key: string, selector: (v: unknown) => unknown = v => v) =>
selector(key === 'plan'
? over?.plan
: key === 'goal' ? over?.goal
: key === 'imageLimits' ? over?.imageLimits
: key === 'contextPressure' ? over?.contextPressure : undefined)),
: key === 'conversationContinuation' ? over?.retryableFailure
: key === 'inbox' ? { 'next-turn': over?.queue ?? [], 'next-step': over?.nextStep ?? [] }
: key === 'imageLimits' ? over?.imageLimits
: key === 'contextPressure' ? over?.contextPressure : undefined)),
useInput: bindSnapshotSelector(shell.state),
inputActions: shell.actions,
keyboard: shell,
@@ -216,6 +220,7 @@ function bench(over?: BenchOptions) {
}),
toggleCommandMenu: over?.toggleCommandMenu ?? vi.fn(),
useBusyEnter: bindSnapshotSelector(busyEnter),
retry,
useStopShortcut: bindSnapshotSelector(stopShortcut),
useNotices: bindSnapshotSelector(shell.notices),
useLexicon: bindSnapshotSelector(shell.lexicon),
@@ -252,20 +257,47 @@ function bench(over?: BenchOptions) {
const plainMessageDraft = sendableDraft && !uploadsPending && !(over?.draft?.trimStart().startsWith('/') ?? false)
const primaryLabel = primaryStops
? '停止生成'
: over?.running === true && steeringAvailable && !composerLocked && plainMessageDraft
? (over.busyEnter === 'steer' ? '插话发送' : '排队发送')
: '发送消息'
: over?.retryableFailure !== undefined && !sendableDraft && over.running !== true && over.subagent === undefined && !composerLocked
&& !(over.nextStep ?? []).some(message => message.source.kind === 'user')
? '继续生成'
: over?.running === true && steeringAvailable && !composerLocked && plainMessageDraft
? (over.busyEnter === 'steer' ? '插话发送' : '排队发送')
: '发送消息'
const button = view.container.querySelector<HTMLButtonElement>(`button[aria-label="${primaryLabel}"]`)!
const interruptButton = view.container.querySelector<HTMLButtonElement>('button[aria-label="停止生成"]')
return {
view, textarea, button, interruptButton, props, sink, shell, wiring: shell, session, stop, removeAttachment, slotCalls,
menuLauncher, busyEnter, stopShortcut,
menuLauncher, busyEnter, stopShortcut, retry,
steerQueue: over?.steerQueue,
get placeholder() { return placeholderOf(view.container) },
get inputDisabled() { return textarea.getAttribute('aria-disabled') === 'true' },
}
}
it('offers the play action only for an empty, idle composer with an eligible failure', async () => {
const b = bench({ retryableFailure: 2 as SessionSeq })
expect(b.button.disabled).toBe(false)
expect(b.button.querySelector('svg')).not.toBeNull()
fireEvent.click(b.button)
expect(b.retry).toHaveBeenCalledExactlyOnceWith(2)
expect(b.sink).not.toHaveBeenCalled()
await act(async () => { b.shell.setDraft('A new instruction') })
const send = b.view.getByRole('button', { name: '发送消息' })
fireEvent.click(send)
await vi.waitFor(() => { expect(b.sink).toHaveBeenCalledOnce() })
expect(b.sink.mock.calls[0]?.[0]).toBe('A new instruction')
expect(b.retry).toHaveBeenCalledOnce()
})
it.each([
{ running: true }, { attachments: [{ kind: 'image' as const, id: 'image' as DraftAttachmentId, file: new File([], 'x.png'), previewUrl: 'blob:test' }] },
{ blocked: { reason: 'Select a model' } }, { subagent: CONTINUABLE_CHILD }, { deniedEndpoints: ['session/prompt'] },
{ nextStep: [row('new instruction')] },
])('keeps the continue action unavailable with %j', (options) => {
const b = bench({ ...options, retryableFailure: 2 as SessionSeq })
expect(b.view.queryByRole('button', { name: '继续生成' })).toBeNull()
})
function attachmentOwner(slotCalls: readonly { key: string; owner: unknown }[]): ComposerAttachmentsOwnerProps {
for (let i = slotCalls.length - 1; i >= 0; i -= 1) {
const call = slotCalls[i]
@@ -86,6 +86,7 @@ function mountBar(shell: SessionInputShell, over?: { running?: boolean; disabled
})),
toggleCommandMenu: vi.fn(),
useBusyEnter: bindSnapshotSelector(createSnapshotStore<'queue' | 'steer'>('queue')),
retry: undefined,
useStopShortcut: bindSnapshotSelector(createSnapshotStore<readonly string[]>([])),
useNotices: bindSnapshotSelector(shell.notices),
useLexicon: bindSnapshotSelector(shell.lexicon),
@@ -202,6 +202,7 @@ async function scopedBench(register?: (inputTriggers: InputTriggerService) => vo
useMenuLauncher: bindSnapshotSelector(controller.launcher),
renderSlot: (() => null) as InputBarProps['renderSlot'],
stop: vi.fn(),
retry: undefined,
useStopShortcut: bindSnapshotSelector(createSnapshotStore<readonly string[]>([])),
t: makeTranslate(zh, commonZh),
variant: 'composer',
@@ -315,6 +315,7 @@ function mount(
resolveDraftAttachments={() => []}
toggleCommandMenu={vi.fn()}
useBusyEnter={bindSnapshotSelector(createSnapshotStore<'queue' | 'steer'>('queue'))}
retry={undefined}
useStopShortcut={bindSnapshotSelector(createSnapshotStore<readonly string[]>([]))}
useNotices={bindSnapshotSelector(wiring.notices)}
useLexicon={bindSnapshotSelector(wiring.lexicon)}
@@ -110,6 +110,7 @@
}
],
"exclude": [
"src/index.ts"
"src/index.ts",
"src/host"
]
}
+3
View File
@@ -4277,6 +4277,9 @@ importers:
'@deepseek-ai/dsh-session':
specifier: workspace:*
version: link:../../core/session
'@deepseek-ai/dsh-session-projection':
specifier: workspace:*
version: link:../../session/session-projection
'@deepseek-ai/dsh-settings':
specifier: workspace:*
version: link:../../settings/settings
@@ -148,7 +148,6 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
'packages/client/ui-sidebar-right': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' },
'packages/client/ui-sidebar': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' },
'packages/client/ui-brand-official': { kind: 'none', reason: 'Browser-side presentation occupants; registers nothing model-facing.' },
'packages/client/ui-conversation': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' },
'packages/client/ui-approval': { kind: 'none', reason: 'Browser-side approval presentation; registers nothing model-facing.' },
'packages/client/ui-chat': { kind: 'none', reason: 'Browser-side Chat presentation; registers nothing model-facing.' },
'packages/client/ui-message-feedback': { kind: 'none', reason: 'Browser-side controls over log-only message feedback; ratings and notes never enter model context or change model-input tokens.' },
@@ -0,0 +1,39 @@
- banner:
- navigation "Session hierarchy": Reply with a one-sentence description
- text: Standard mode
- button "More actions"
- button "Open right sidebar"
- tablist:
- tab "Chat" [selected]
- tab "Trajectory"
- button "More conversation views"
- navigation "Turn navigation":
- button "Jump to turn 1"
- button "Jump to turn 2"
- text: Reply with a one-sentence description of event sourcing, then stop. {{clock}}
- button "Copy"
- status: Failed
- button "Failed" [disabled] [expanded]
- button "Injected context"
- group:
- status: Retried model request (2/2) · {{duration}}
- status:
- text: This turn failedupstream 503
- code: SERVER
- text: plan Plan mode on. Use /plan off to leave. plan Plan mode off. Requested to continue generation
- status: Completed
- button "Completed in {{duration}}"
- paragraph: Event sourcing is a pattern where all changes to an application's state are stored as an immutable, append-only sequence of events, rather than persisting only the current state, enabling full auditability, temporal queries, and event-driven architectures.
- button "Copy"
- button "Good response"
- button "Bad response"
- button "Branch into a new conversation"
- text: {{clock}}
- textbox "Message or run a task, / commands, @ files or sessions"
- button "Add files or run commands"
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash": DeepSeek-V4-Flash
- button "Send message" [disabled]
- button "2 turns 2 steps · {{throughput}} tok/s": 2 turns 2 steps{{throughput}} tok/s
- button "7.9K tok · Cache hit 99%": 7.9K tokCache hit 99%
- button "6% of context used": 6%
@@ -21,5 +21,5 @@
- button "Add files or run commands"
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash": DeepSeek-V4-Flash
- button "Send message" [disabled]
- button "Continue generating"
- text: 1 turns 1 steps